From 9e8f577a837b3f8d7d29bbb37717208d420e61f2 Mon Sep 17 00:00:00 2001 From: Oleksandr Panasiuk Date: Tue, 14 Mar 2023 18:06:33 +0200 Subject: [PATCH] Rehost BindingReflections.loadModuleInfos() Use ServiceLoader to locate all module infos instead. This reduces the proliferation of BindingReflections just a tiny bit. JIRA: MDSAL-803 Change-Id: I5d76f6c8eddc1d689ebd8fcbe9cbf23350b465cf Signed-off-by: Oleksandr Panasiuk Signed-off-by: Robert Varga --- .../adapter/test/util/BindingTestContext.java | 5 +-- .../src/main/java/module-info.java | 1 + .../runtime/spi/BindingRuntimeHelpers.java | 41 ++++++++++++++----- .../spi/ModuleInfoSnapshotBuilder.java | 2 +- .../spec/reflect/BindingReflections.java | 10 ----- .../spec/reflect/BindingReflectionsTest.java | 3 -- 6 files changed, 33 insertions(+), 29 deletions(-) diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/BindingTestContext.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/BindingTestContext.java index dd06d7e63f..c57b2f8746 100644 --- a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/BindingTestContext.java +++ b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/BindingTestContext.java @@ -11,7 +11,6 @@ import static com.google.common.base.Preconditions.checkState; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import java.util.Set; @@ -29,7 +28,6 @@ import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationServiceA import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMRpcProviderServiceAdapter; import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMRpcServiceAdapter; import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers; -import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMMountPointService; @@ -184,8 +182,7 @@ public class BindingTestContext implements AutoCloseable { } public void loadYangSchemaFromClasspath() { - final ImmutableSet moduleInfos = BindingReflections.loadModuleInfos(); - updateYangSchema(moduleInfos); + updateYangSchema(BindingRuntimeHelpers.loadModuleInfos()); } public DOMRpcProviderService getDomRpcRegistry() { diff --git a/binding/mdsal-binding-runtime-spi/src/main/java/module-info.java b/binding/mdsal-binding-runtime-spi/src/main/java/module-info.java index ea8a90c818..73b77f818b 100644 --- a/binding/mdsal-binding-runtime-spi/src/main/java/module-info.java +++ b/binding/mdsal-binding-runtime-spi/src/main/java/module-info.java @@ -18,6 +18,7 @@ module org.opendaylight.mdsal.binding.runtime.spi { requires org.opendaylight.mdsal.binding.spec.util; requires org.slf4j; + uses org.opendaylight.yangtools.yang.binding.YangModelBindingProvider; uses org.opendaylight.yangtools.yang.parser.api.YangParserFactory; uses org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator; diff --git a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/BindingRuntimeHelpers.java b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/BindingRuntimeHelpers.java index d724dd498f..0e5a488318 100644 --- a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/BindingRuntimeHelpers.java +++ b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/BindingRuntimeHelpers.java @@ -7,10 +7,13 @@ */ package org.opendaylight.mdsal.binding.runtime.spi; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.annotations.Beta; -import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableSet; import java.util.Arrays; import java.util.Collection; +import java.util.ServiceLoader; import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; @@ -18,6 +21,7 @@ import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator; import org.opendaylight.mdsal.binding.runtime.api.DefaultBindingRuntimeContext; import org.opendaylight.mdsal.binding.runtime.api.ModuleInfoSnapshot; import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; +import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.parser.api.YangParserException; @@ -31,7 +35,7 @@ import org.opendaylight.yangtools.yang.parser.api.YangParserFactory; @Beta public final class BindingRuntimeHelpers { private BindingRuntimeHelpers() { - + // Hidden on purpose } public static @NonNull EffectiveModelContext createEffectiveModel(final Class... classes) { @@ -57,8 +61,7 @@ public final class BindingRuntimeHelpers { public static @NonNull BindingRuntimeContext createRuntimeContext() { final ModuleInfoSnapshot infos; try { - infos = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE, - BindingReflections.loadModuleInfos()); + infos = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE, loadModuleInfos()); } catch (YangParserException e) { throw new IllegalStateException("Failed to parse models", e); } @@ -102,13 +105,29 @@ public final class BindingRuntimeHelpers { return new DefaultBindingRuntimeContext(generator.generateTypeMapping(infos.getEffectiveModelContext()), infos); } - @SuppressWarnings("checkstyle:IllegalCatch") - private static @NonNull YangModuleInfo extractYangModuleInfo(final Class clazz) { - try { - return BindingReflections.getModuleInfo(clazz); - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new IllegalStateException("Failed to extract module info from " + clazz, e); + public static @NonNull YangModuleInfo extractYangModuleInfo(final Class clazz) { + final var namespace = BindingReflections.findQName(clazz).getNamespace(); + return loadModuleInfos().stream() + .filter(info -> namespace.equals(info.getName().getNamespace())) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Failed to extract module info from " + clazz)); + } + + public static @NonNull ImmutableSet loadModuleInfos() { + final var moduleInfoSet = ImmutableSet.builder(); + for (var bindingProvider : ServiceLoader.load(YangModelBindingProvider.class)) { + var moduleInfo = bindingProvider.getModuleInfo(); + checkState(moduleInfo != null, "Module Info for %s is not available.", bindingProvider.getClass()); + collectYangModuleInfo(bindingProvider.getModuleInfo(), moduleInfoSet); + } + return moduleInfoSet.build(); + } + + private static void collectYangModuleInfo(final YangModuleInfo moduleInfo, + final ImmutableSet.Builder moduleInfoSet) { + moduleInfoSet.add(moduleInfo); + for (var dependency : moduleInfo.getImportedModules()) { + collectYangModuleInfo(dependency, moduleInfoSet); } } diff --git a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ModuleInfoSnapshotBuilder.java b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ModuleInfoSnapshotBuilder.java index 457397cd60..89dd34d983 100644 --- a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ModuleInfoSnapshotBuilder.java +++ b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ModuleInfoSnapshotBuilder.java @@ -52,7 +52,7 @@ public final class ModuleInfoSnapshotBuilder { public @NonNull ModuleInfoSnapshotBuilder add(final Class clazz) { final YangModuleInfo moduleInfo; try { - moduleInfo = BindingReflections.getModuleInfo(clazz); + moduleInfo = BindingRuntimeHelpers.extractYangModuleInfo(clazz); } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new IllegalStateException("Failed to introspect " + clazz, e); diff --git a/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java b/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java index 34ce3e23bd..847ca2d97b 100644 --- a/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java +++ b/binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java @@ -231,16 +231,6 @@ public final class BindingReflections { return Notification.class.isAssignableFrom(potentialNotification); } - /** - * Loads {@link YangModuleInfo} infos available on current classloader. This method is shorthand for - * {@link #loadModuleInfos(ClassLoader)} with {@link Thread#getContextClassLoader()} for current thread. - * - * @return Set of {@link YangModuleInfo} available for current classloader. - */ - public static @NonNull ImmutableSet loadModuleInfos() { - return loadModuleInfos(Thread.currentThread().getContextClassLoader()); - } - /** * Loads {@link YangModuleInfo} infos available on supplied classloader. * diff --git a/binding/mdsal-binding-spec-util/src/test/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflectionsTest.java b/binding/mdsal-binding-spec-util/src/test/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflectionsTest.java index e04eee6b45..6d4e55635d 100644 --- a/binding/mdsal-binding-spec-util/src/test/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflectionsTest.java +++ b/binding/mdsal-binding-spec-util/src/test/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflectionsTest.java @@ -12,7 +12,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Collections; import java.util.List; import org.junit.Test; import org.opendaylight.yangtools.yang.binding.Augmentation; @@ -27,8 +26,6 @@ public class BindingReflectionsTest { public void testBindingWithDummyObject() throws Exception { assertEquals("ModuleInfoClassName should be equal to string", "test.$YangModuleInfoImpl", BindingReflections.getModuleInfoClassName("test")); - assertEquals("Module info should be empty Set", Collections.emptySet(), - BindingReflections.loadModuleInfos()); assertFalse("Should not be RpcType", BindingReflections.isRpcType(DataObject.class)); assertTrue("Should be BindingClass", BindingReflections.isBindingClass(DataObject.class)); assertFalse("Should not be Notification", BindingReflections.isNotification(DataObject.class)); -- 2.36.6