<artifactId>metainf-services</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.cmpn</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-yangtools-parser">
<feature name="odl-yangtools-parser">
<feature version="[6,7)">odl-antlr4</feature>
+ <feature>scr</feature>
</feature>
</features>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="odl-yangtools-xpath">
+ <feature name="odl-yangtools-xpath">
+ <feature>scr</feature>
+ </feature>
+</features>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-rfc7950</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-xpath-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>rfc6241-model-api</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-rfc7950</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-xpath-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>rfc6536-model-api</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-rfc7950</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-xpath-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>rfc7952-model-api</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-rfc7950</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-xpath-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>rfc8040-model-api</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-rfc7950</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-xpath-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>rfc8528-model-api</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-rfc7950</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-xpath-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<artifactId>yang-xpath-impl</artifactId>
</dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
<dependency>
<groupId>org.kohsuke.metainf-services</groupId>
<artifactId>metainf-services</artifactId>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
+ <artifactId>osgi.cmpn</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
</dependency>
</dependencies>
<configuration>
<instructions>
<Automatic-Module-Name>org.opendaylight.yangtools.yang.parser.impl</Automatic-Module-Name>
- <Bundle-Activator>org.opendaylight.yangtools.yang.parser.impl.osgi.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
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.
*/
@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
* @return a shared default-configured reactor instance.
*/
public static @NonNull CrossSourceStatementReactor defaultReactor() {
- return DEFAULT_REACTOR;
+ return DefaultReactor.INSTANCE;
}
/**
*
* @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())
--- /dev/null
+/*
+ * 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<StatementParserMode> supportedParserModes() {
+ return delegate.supportedParserModes();
+ }
+
+ @Override
+ public YangParser createParser(final StatementParserMode parserMode) {
+ return delegate.createParser(parserMode);
+ }
+}
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.
*/
@Beta
@MetaInfServices
+@Singleton
public final class YangParserFactoryImpl implements YangParserFactory {
private static final ImmutableList<StatementParserMode> SUPPORTED_MODES = ImmutableList.of(
StatementParserMode.DEFAULT_MODE, StatementParserMode.SEMVER_MODE);
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);
}
+++ /dev/null
-/*
- * 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;
- }
- }
-}
+++ /dev/null
-/*
- * 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
.put(ModelProcessingPhase.EFFECTIVE_MODEL, StatementSupportBundle.builder(supportedVersions)).build();
}
- public CustomCrossSourceStatementReactorBuilder addStatementSupport(final ModelProcessingPhase phase,
+ public @NonNull CustomCrossSourceStatementReactorBuilder addStatementSupport(final ModelProcessingPhase phase,
final StatementSupport<?, ?, ?> 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<StatementDefinition> validationBundle) {
+ public @NonNull CustomCrossSourceStatementReactorBuilder addValidationBundle(
+ final ValidationBundleType validationBundleType, final Collection<StatementDefinition> 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());
return this;
}
- public CustomCrossSourceStatementReactorBuilder addAllNamespaceSupports(final ModelProcessingPhase phase,
+ public @NonNull CustomCrossSourceStatementReactorBuilder addAllNamespaceSupports(final ModelProcessingPhase phase,
final Collection<NamespaceBehaviour<?, ?, ?>> namespaceSupports) {
final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
for (final NamespaceBehaviour<?, ?, ?> namespaceSupport : namespaceSupports) {
return this;
}
- public CustomCrossSourceStatementReactorBuilder addAllCommonStatementSupports(final ModelProcessingPhase phase,
- final Collection<StatementSupport<?, ?, ?>> statementSupports) {
+ public @NonNull CustomCrossSourceStatementReactorBuilder addAllCommonStatementSupports(
+ final ModelProcessingPhase phase, final Collection<StatementSupport<?, ?, ?>> statementSupports) {
final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
for (final StatementSupport<?, ?, ?> statementSupport : statementSupports) {
stmtBundleBuilder.addSupport(statementSupport);
return this;
}
- public CustomCrossSourceStatementReactorBuilder addAllVersionSpecificSupports(final ModelProcessingPhase phase,
+ public @NonNull CustomCrossSourceStatementReactorBuilder addAllVersionSpecificSupports(
+ final ModelProcessingPhase phase,
final Table<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificSupports) {
final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase);
for (final Cell<YangVersion, QName, StatementSupport<?, ?, ?>> cell : versionSpecificSupports.cellSet()) {
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;
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.
.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<ModelProcessingPhase, StatementSupportBundle> RFC7950_BUNDLES =
- ImmutableMap.<ModelProcessingPhase, StatementSupportBundle>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<ValidationBundleType, Collection<StatementDefinition>> RFC6020_VALIDATION_BUNDLE =
- ImmutableMap.<ValidationBundleType, Collection<StatementDefinition>>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
*
* @return A shared reactor instance.
*/
- public static CrossSourceStatementReactor defaultReactor() {
- return DEFAULT_RFC6020_RFC7950_REACTOR;
+ public static @NonNull CrossSourceStatementReactor defaultReactor() {
+ return ServiceLoaderState.DefaultReactor.INSTANCE;
}
/**
*
* @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)
*
* @return A shared reactor instance.
*/
- public static CrossSourceStatementReactor vanillaReactor() {
- return VANILLA_RFC6020_RFC7950_REACTOR;
+ public static @NonNull CrossSourceStatementReactor vanillaReactor() {
+ return ServiceLoaderState.VanillaReactor.INSTANCE;
}
/**
*
* @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();
}
}
--- /dev/null
+/*
+ * 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")));
+ }
+}
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;
}
}
- 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();
}
*/
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;
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<YangXPathParserFactory> 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);
}
}
*/
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;
.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
*/
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;
.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
</dependency>
<dependency>
<groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
+ <artifactId>osgi.cmpn</artifactId>
</dependency>
</dependencies>
<configuration>
<instructions>
<Automatic-Module-Name>org.opendaylight.yangtools.yang.xpath.impl</Automatic-Module-Name>
- <Bundle-Activator>org.opendaylight.yangtools.yang.xpath.impl.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
+++ /dev/null
-/*
- * 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
- }
-}
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);
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");
+ }
}