Eliminate ClassLoadingStrategy 04/92804/5
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Sep 2020 10:43:56 +0000 (12:43 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Sep 2020 14:55:25 +0000 (16:55 +0200)
ClassLoadingStrategy as a separate concept is very confusing. The
reality is that ModuleInfoSnapshot needs to be able to load classes
based on their FQCN and BindingRuntimeContext needs to do the same
based on they binding.model.api.Type.

Split ClassLoadingStrategy's two methods appropriately and remove
it. Also adjust all users to not rely on it.

JIRA: MDSAL-578
Change-Id: Id4606efcd67d8ea7c42e78c48c48aa915cb11a52
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
23 files changed:
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeChangeServiceAdapterTest.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/CurrentAdapterSerializerTest.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/MockAdapterContext.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/TestingModuleInfoSnapshot.java [new file with mode: 0644]
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataContainerCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentationClassDiscoveredAfterCodecTest.java [deleted file]
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeContext.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/ClassLoadingStrategy.java [deleted file]
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/DefaultBindingRuntimeContext.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/ModuleInfoSnapshot.java
binding/mdsal-binding-runtime-osgi/src/main/java/org/opendaylight/mdsal/binding/runtime/osgi/impl/OSGiBindingRuntime.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/BindingRuntimeHelpers.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/DefaultModuleInfoSnapshot.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingBindingRuntimeContext.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingModuleInfoSnapshot.java
yanglib/mdsal-yanglib-rfc7895/pom.xml
yanglib/mdsal-yanglib-rfc7895/src/main/java/org/opendaylight/mdsal/yanglib/rfc7895/SimpleStrategy.java [deleted file]
yanglib/mdsal-yanglib-rfc7895/src/main/java/org/opendaylight/mdsal/yanglib/rfc7895/YangModuleLibrarySupport.java
yanglib/mdsal-yanglib-rfc8525/pom.xml
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/SimpleStrategy.java [deleted file]
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupport.java

index f7e9422b5f0d8d8b7851c9fadc394f4da58d92fd..ad1127335820b23b8b51a9421fc97ecc8de3ffba 100644 (file)
@@ -27,7 +27,6 @@ import org.opendaylight.mdsal.binding.api.DataTreeChangeService;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
@@ -50,9 +49,6 @@ public class BindingDOMDataTreeChangeServiceAdapterTest {
     @Mock
     private DOMDataTreeChangeService mockDOMService;
 
-    @Mock
-    private ClassLoadingStrategy classLoadingStrategy;
-
     @Mock
     private BindingDOMCodecServices services;
 
index 86e2982f6929052dc702b29b365135995db27a03..e0cd4a0ad7d0decd8fe2ada7e35f54f7ab7d078e 100644 (file)
@@ -18,10 +18,10 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map.Entry;
 import org.junit.Test;
+import org.opendaylight.mdsal.binding.dom.adapter.test.util.TestingModuleInfoSnapshot;
 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext;
 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 import org.opendaylight.mdsal.binding.runtime.api.DefaultBindingRuntimeContext;
-import org.opendaylight.yangtools.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -111,8 +111,8 @@ public class CurrentAdapterSerializerTest {
     private static Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode(final NormalizedNode<?, ?> data,
             final EffectiveModelContext schemaCtx) {
         final CurrentAdapterSerializer codec = new CurrentAdapterSerializer(new BindingCodecContext(
-            DefaultBindingRuntimeContext.create(new DefaultBindingRuntimeGenerator().generateTypeMapping(schemaCtx),
-                ClassLoaderUtils::loadClassWithTCCL)));
+            new DefaultBindingRuntimeContext(new DefaultBindingRuntimeGenerator().generateTypeMapping(schemaCtx),
+                    TestingModuleInfoSnapshot.INSTANCE)));
 
         final YangInstanceIdentifier path = YangInstanceIdentifier.create(NodeIdentifier.create(QName.create(
             "urn:test", "2017-01-01", "cont")));
index bfa1fb61fba2a54fb8f6fed0fe7eb146be90ea9a..c0152aeb213103546158ae5d3370445576883d12 100644 (file)
@@ -14,7 +14,6 @@ import org.opendaylight.mdsal.binding.dom.adapter.CurrentAdapterSerializer;
 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext;
 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 import org.opendaylight.mdsal.binding.runtime.api.DefaultBindingRuntimeContext;
-import org.opendaylight.yangtools.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener;
 
@@ -28,8 +27,8 @@ public final class MockAdapterContext implements AdapterContext, EffectiveModelC
 
     @Override
     public void onModelContextUpdated(final EffectiveModelContext newModelContext) {
-        serializer = new CurrentAdapterSerializer(new BindingCodecContext(DefaultBindingRuntimeContext.create(
+        serializer = new CurrentAdapterSerializer(new BindingCodecContext(new DefaultBindingRuntimeContext(
             new DefaultBindingRuntimeGenerator().generateTypeMapping(newModelContext),
-            ClassLoaderUtils::loadClassWithTCCL)));
+                TestingModuleInfoSnapshot.INSTANCE)));
     }
 }
diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/TestingModuleInfoSnapshot.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/util/TestingModuleInfoSnapshot.java
new file mode 100644 (file)
index 0000000..159f350
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.mdsal.binding.dom.adapter.test.util;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.mdsal.binding.runtime.api.ModuleInfoSnapshot;
+import org.opendaylight.yangtools.util.ClassLoaderUtils;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+
+public final class TestingModuleInfoSnapshot implements ModuleInfoSnapshot {
+    public static final TestingModuleInfoSnapshot INSTANCE = new TestingModuleInfoSnapshot();
+
+    private TestingModuleInfoSnapshot() {
+        // Hidden on purpose
+    }
+
+    @Override
+    public EffectiveModelContext getEffectiveModelContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ListenableFuture<? extends YangTextSchemaSource> getSource(SourceIdentifier sourceIdentifier) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T> Class<T> loadClass(String fullyQualifiedName) throws ClassNotFoundException {
+        return (Class<T>) ClassLoaderUtils.loadClassWithTCCL(fullyQualifiedName);
+    }
+}
index 5814671b0f43e932031fa8f151e8b4a313bbdcc0..e8bca5d0d1e5cde58b6f64affad6f8521c92f2eb 100644 (file)
@@ -27,8 +27,8 @@ import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
 import org.opendaylight.mdsal.binding.dom.codec.api.MissingClassInLoadingStrategyException;
 import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaException;
 import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaForClassException;
+import org.opendaylight.mdsal.binding.model.api.DefaultType;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BindingObject;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -211,12 +211,11 @@ abstract class DataContainerCodecContext<D extends DataObject, T extends WithSta
             throw new MissingSchemaForClassException(childClass);
         }
 
-        final ClassLoadingStrategy strategy = runtimeContext.getStrategy();
         try {
-            strategy.loadClass(childClass.getName());
+            runtimeContext.loadClass(DefaultType.of(childClass));
         } catch (final ClassNotFoundException e) {
             throw new MissingClassInLoadingStrategyException(
-                "User supplied class " + childClass.getName() + " is not available in " + strategy, e);
+                "User supplied class " + childClass.getName() + " is not available in " + runtimeContext, e);
         }
 
         throw IncorrectNestingException.create(message, args);
index cfe4f91f4f159bebff217c61a8d85cd000f916b9..79ec825abf40a4d7b759620beba35af4dde878d6 100644 (file)
@@ -31,7 +31,7 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
 import org.opendaylight.mdsal.binding.model.api.Type;
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.util.ClassLoaderUtils;
@@ -489,19 +489,19 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Dat
     }
 
     private DataContainerCodecPrototype<?> getAugmentationPrototype(final Type value) {
-        final ClassLoadingStrategy loader = factory().getRuntimeContext().getStrategy();
-        @SuppressWarnings("rawtypes")
-        final Class augClass;
+        final BindingRuntimeContext ctx = factory().getRuntimeContext();
+
+        final Class<? extends Augmentation<?>> augClass;
         try {
-            augClass = loader.loadClass(value);
+            augClass = ctx.loadClass(value);
         } catch (final ClassNotFoundException e) {
+            // FIXME: MDSAL-578: this is disallowed
             LOG.debug("Failed to load augmentation prototype for {}. Will be retried when needed.", value, e);
             return null;
         }
 
-        @SuppressWarnings("unchecked")
-        final Entry<AugmentationIdentifier, AugmentationSchemaNode> augSchema = factory().getRuntimeContext()
-                .getResolvedAugmentationSchema(getSchema(), augClass);
+        final Entry<AugmentationIdentifier, AugmentationSchemaNode> augSchema =
+                ctx.getResolvedAugmentationSchema(getSchema(), augClass);
         return DataContainerCodecPrototype.from(augClass, augSchema.getKey(), augSchema.getValue(), factory());
     }
 
diff --git a/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentationClassDiscoveredAfterCodecTest.java b/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentationClassDiscoveredAfterCodecTest.java
deleted file mode 100644 (file)
index fe94136..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. 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.mdsal.binding.dom.codec.impl;
-
-import static java.util.Objects.requireNonNull;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.HashSet;
-import java.util.Map.Entry;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.mdsal.binding.dom.codec.api.MissingClassInLoadingStrategyException;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
-import org.opendaylight.mdsal.binding.runtime.api.DefaultBindingRuntimeContext;
-import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugment;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugmentBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * This sets of tests are designed in way, that schema context contains models for all augmentations, but backing class
- * loading strategy is not aware of some of the classes, and becames aware of them after codec was used.
- *
- * <p>
- * The idea of this suite is to test that codecs will work even if situation like this happens.
- */
-public class AugmentationClassDiscoveredAfterCodecTest {
-    private BindingNormalizedNodeSerializer serializer;
-    private FilteringClassLoadingStrategy filter;
-
-    @Before
-    public void setup() {
-        // Baseline state: strategy is cognizant of the classes
-        final BindingRuntimeContext delegate = BindingRuntimeHelpers.createRuntimeContext();
-
-        // Class loading filter, manipulated by tests
-        filter = new FilteringClassLoadingStrategy(delegate.getStrategy());
-        serializer = new BindingCodecContext(DefaultBindingRuntimeContext.create(delegate.getTypes(), filter));
-    }
-
-    private static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo");
-    private static final InstanceIdentifier<TopLevelList> BA_TOP_LEVEL_LIST = InstanceIdentifier.builder(Top.class)
-            .child(TopLevelList.class, TOP_FOO_KEY).build();
-    private static final InstanceIdentifier<TreeLeafOnlyAugment> BA_TREE_LEAF_ONLY = BA_TOP_LEVEL_LIST
-            .augmentation(TreeLeafOnlyAugment.class);
-
-    @Test(expected = MissingClassInLoadingStrategyException.class)
-    public void testCorrectExceptionThrown() {
-        materializeWithExclusions(TreeLeafOnlyAugment.class, TreeComplexUsesAugment.class);
-        serializer.toYangInstanceIdentifier(BA_TREE_LEAF_ONLY);
-    }
-
-    @Test
-    public void testUsingBindingInstanceIdentifier() {
-        materializeWithExclusions(TreeLeafOnlyAugment.class, TreeComplexUsesAugment.class);
-        filter.includeClass(TreeLeafOnlyAugment.class);
-        final YangInstanceIdentifier domYY = serializer.toYangInstanceIdentifier(BA_TREE_LEAF_ONLY);
-        assertNotNull(domYY);
-    }
-
-    @Test
-    public void testUsingBindingData() {
-        materializeWithExclusions(TreeLeafOnlyAugment.class, TreeComplexUsesAugment.class);
-        filter.includeClass(TreeLeafOnlyAugment.class);
-        final TopLevelList data = new TopLevelListBuilder()
-                .withKey(TOP_FOO_KEY)
-                .addAugmentation(new TreeLeafOnlyAugmentBuilder().setSimpleValue("foo").build())
-                .build();
-        final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> domData =
-                serializer.toNormalizedNode(BA_TOP_LEVEL_LIST, data);
-        assertNotNull(domData);
-    }
-
-    private void materializeWithExclusions(final Class<?>... clzToExclude) {
-        for (final Class<?> clz : clzToExclude) {
-            filter.excludeClass(clz);
-        }
-        serializer.toYangInstanceIdentifier(BA_TOP_LEVEL_LIST);
-    }
-
-    private static final class FilteringClassLoadingStrategy implements ClassLoadingStrategy {
-        private final Set<String> exclusions = new HashSet<>();
-        private final ClassLoadingStrategy delegate;
-
-        FilteringClassLoadingStrategy(final ClassLoadingStrategy delegate) {
-            this.delegate = requireNonNull(delegate);
-        }
-
-        void excludeClass(final Class<?> clz) {
-            exclusions.add(clz.getName());
-        }
-
-        void includeClass(final Class<?> clz) {
-            exclusions.remove(clz.getName());
-        }
-
-        @Override
-        public Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
-            if (exclusions.contains(fullyQualifiedName)) {
-                throw new ClassNotFoundException(String.format("Class %s is not available for test reasons.",
-                        fullyQualifiedName));
-            }
-            return delegate.loadClass(fullyQualifiedName);
-        }
-    }
-}
index 33a0a1ba6ccfa58559d0100b4380c9ab8bba7448..920d11546b67dce331ec1c05c9c8d4828f9450a6 100644 (file)
@@ -72,7 +72,7 @@ public abstract class AbstractBindingRuntimeContext implements BindingRuntimeCon
                 final Optional<Type> identityType = getTypes().findIdentity(key);
                 checkArgument(identityType.isPresent(), "Supplied QName %s is not a valid identity", key);
                 try {
-                    return getStrategy().loadClass(identityType.get());
+                    return loadClass(identityType.get());
                 } catch (final ClassNotFoundException e) {
                     throw new IllegalArgumentException("Required class " + identityType + "was not found.", e);
                 }
@@ -268,7 +268,7 @@ public abstract class AbstractBindingRuntimeContext implements BindingRuntimeCon
         final Set<Class<?>> ret = new HashSet<>(cazes.size());
         for (final Type caze : cazes) {
             try {
-                ret.add(getStrategy().loadClass(caze));
+                ret.add(loadClass(caze));
             } catch (final ClassNotFoundException e) {
                 LOG.warn("Failed to load class for case {}, ignoring it", caze, e);
             }
@@ -284,7 +284,7 @@ public abstract class AbstractBindingRuntimeContext implements BindingRuntimeCon
             childSchema, origSchema);
 
         try {
-            return getStrategy().loadClass(clazzType.get());
+            return loadClass(clazzType.get());
         } catch (final ClassNotFoundException e) {
             throw new IllegalStateException(e);
         }
index f375c134268be6f85a7eb62c9475df7d614a8daa..99b98d1c3365b347f4c8f2dd83ccd04a3779716d 100644 (file)
@@ -45,16 +45,10 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absol
  */
 @Beta
 public interface BindingRuntimeContext extends EffectiveModelContextProvider, Immutable {
-    /**
-     * Returns a class loading strategy associated with this binding runtime context
-     * which is used to load classes.
-     *
-     * @return Class loading strategy.
-     */
-    @NonNull ClassLoadingStrategy getStrategy();
-
     @NonNull BindingRuntimeTypes getTypes();
 
+    @NonNull <T> Class<T> loadClass(Type type) throws ClassNotFoundException;
+
     @Override
     default EffectiveModelContext getEffectiveModelContext() {
         return getTypes().getEffectiveModelContext();
diff --git a/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/ClassLoadingStrategy.java b/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/ClassLoadingStrategy.java
deleted file mode 100644 (file)
index dc47d33..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.mdsal.binding.runtime.api;
-
-import org.opendaylight.mdsal.binding.model.api.Type;
-
-public interface ClassLoadingStrategy {
-
-    default Class<?> loadClass(final Type type) throws ClassNotFoundException {
-        return loadClass(type.getFullyQualifiedName());
-    }
-
-    Class<?> loadClass(String fullyQualifiedName) throws ClassNotFoundException;
-}
index 0e658e884bce4339fb539e2a7bcc4d462ea64e97..a4c1da1e2b7ca01e82ba19452dc9507a6a334260 100644 (file)
@@ -11,6 +11,7 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 
 /**
@@ -24,38 +25,20 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 @Beta
 public final class DefaultBindingRuntimeContext extends AbstractBindingRuntimeContext {
     private final @NonNull BindingRuntimeTypes runtimeTypes;
-    private final @NonNull ClassLoadingStrategy strategy;
+    private final @NonNull ModuleInfoSnapshot moduleInfos;
 
-    private DefaultBindingRuntimeContext(final BindingRuntimeTypes runtimeTypes, final ClassLoadingStrategy strategy) {
+    public DefaultBindingRuntimeContext(final BindingRuntimeTypes runtimeTypes, final ModuleInfoSnapshot moduleInfos) {
         this.runtimeTypes = requireNonNull(runtimeTypes);
-        this.strategy = requireNonNull(strategy);
+        this.moduleInfos = requireNonNull(moduleInfos);
     }
 
-    /**
-     * Creates Binding Runtime Context from supplied class loading strategy and schema context.
-     *
-     * @param strategy Class loading strategy to retrieve generated Binding classes
-     * @param runtimeTypes Binding classes to YANG schema mapping
-     * @return A new instance
-     */
-    public static @NonNull DefaultBindingRuntimeContext create(final BindingRuntimeTypes runtimeTypes,
-            final ClassLoadingStrategy strategy) {
-        return new DefaultBindingRuntimeContext(runtimeTypes, strategy);
-    }
-
-    /**
-     * Returns a class loading strategy associated with this binding runtime context
-     * which is used to load classes.
-     *
-     * @return Class loading strategy.
-     */
     @Override
-    public @NonNull ClassLoadingStrategy getStrategy() {
-        return strategy;
+    public BindingRuntimeTypes getTypes() {
+        return runtimeTypes;
     }
 
     @Override
-    public @NonNull BindingRuntimeTypes getTypes() {
-        return runtimeTypes;
+    public <T> Class<T> loadClass(Type type) throws ClassNotFoundException {
+        return moduleInfos.loadClass(type.getFullyQualifiedName());
     }
 }
index ffdbe7f8f4e2df8a7fb1df6246e76678fbaff94e..733511d47727a636ec297adc318370d5d245ec63 100644 (file)
@@ -14,7 +14,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
 
 @Beta
-public interface ModuleInfoSnapshot extends Immutable, ClassLoadingStrategy, EffectiveModelContextProvider,
+public interface ModuleInfoSnapshot extends Immutable, EffectiveModelContextProvider,
         SchemaSourceProvider<YangTextSchemaSource> {
 
+    <T> Class<T> loadClass(String fullyQualifiedName) throws ClassNotFoundException;
 }
index e331142701ae2ce3dfb0462174480807887cf1b3..bce0e0a24bafd967513c93c02255be552f8741a0 100644 (file)
@@ -102,7 +102,7 @@ public final class OSGiBindingRuntime {
 
             instances.put(snapshot, factory.newInstance(OSGiBindingRuntimeContextImpl.props(
                 snapshot.getGeneration(), snapshot.getServiceRanking(),
-                DefaultBindingRuntimeContext.create(types, context))));
+                new DefaultBindingRuntimeContext(types, context))));
         }
 
         @Override
index eb6c0ab6a086c951dab9e88e0684b9b346ba8d3f..a2e0294cce09ed9e9537b6ce2dd4c9e542dd2a1d 100644 (file)
@@ -52,7 +52,7 @@ public final class BindingRuntimeHelpers {
     public static @NonNull BindingRuntimeContext createRuntimeContext() {
         final ModuleInfoSnapshot infos = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE,
             BindingReflections.loadModuleInfos());
-        return DefaultBindingRuntimeContext.create(ServiceLoaderState.Generator.INSTANCE.generateTypeMapping(
+        return new DefaultBindingRuntimeContext(ServiceLoaderState.Generator.INSTANCE.generateTypeMapping(
             infos.getEffectiveModelContext()), infos);
     }
 
@@ -71,8 +71,7 @@ public final class BindingRuntimeHelpers {
         final ModuleInfoSnapshot infos = prepareContext(parserFactory, classes.stream()
             .map(BindingRuntimeHelpers::extractYangModuleInfo)
             .collect(Collectors.toList()));
-        return DefaultBindingRuntimeContext.create(
-            generator.generateTypeMapping(infos.getEffectiveModelContext()), infos);
+        return new DefaultBindingRuntimeContext(generator.generateTypeMapping(infos.getEffectiveModelContext()), infos);
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
index 4047969e8c22089459b0c461caeda208c1f06f00..8178c439ab02838771b4dfb10ad74dd430c6fd45 100644 (file)
@@ -51,12 +51,14 @@ final class DefaultModuleInfoSnapshot implements ModuleInfoSnapshot {
     }
 
     @Override
-    public Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
+    public <T> Class<T> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
         final String packageName = BindingReflections.getModelRootPackageName(fullyQualifiedName);
         final ClassLoader loader = classLoaders.get(packageName);
         if (loader == null) {
             throw new ClassNotFoundException("Package " + packageName + " not found");
         }
-        return loader.loadClass(fullyQualifiedName);
+        @SuppressWarnings("unchecked")
+        final Class<T> loaded = (Class<T>) loader.loadClass(fullyQualifiedName);
+        return loaded;
     }
 }
index fd90b05864dff6c90f894c163627c01aaec85cec..a48d44f0cabbdab084384d8328e8b81d95876660 100644 (file)
@@ -18,7 +18,6 @@ import org.opendaylight.mdsal.binding.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes;
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.yang.binding.Action;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -38,11 +37,6 @@ public abstract class ForwardingBindingRuntimeContext extends ForwardingObject i
     @Override
     protected abstract BindingRuntimeContext delegate();
 
-    @Override
-    public ClassLoadingStrategy getStrategy() {
-        return delegate().getStrategy();
-    }
-
     @Override
     public BindingRuntimeTypes getTypes() {
         return delegate().getTypes();
@@ -108,4 +102,9 @@ public abstract class ForwardingBindingRuntimeContext extends ForwardingObject i
     public Class<?> getIdentityClass(final QName input) {
         return delegate().getIdentityClass(input);
     }
+
+    @Override
+    public <T> Class<T> loadClass(final Type type) throws ClassNotFoundException {
+        return delegate().loadClass(type);
+    }
 }
index 4b3a037756db92d79a32b5e7d1073055aeacec5f..90454856ee7d5356d8af7d8afffe9901378cd5db 100644 (file)
@@ -22,7 +22,7 @@ public abstract class ForwardingModuleInfoSnapshot extends ForwardingObject impl
     protected abstract ModuleInfoSnapshot delegate();
 
     @Override
-    public Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
+    public <T> Class<T> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
         return delegate().loadClass(fullyQualifiedName);
     }
 
index 9dd3ca48e1ace280bda42690ad54d1235dfd1e02..9bcfff78ba02b213641f5d2857527748e727d968 100644 (file)
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding-runtime-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-runtime-spi</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding-dom-codec-api</artifactId>
diff --git a/yanglib/mdsal-yanglib-rfc7895/src/main/java/org/opendaylight/mdsal/yanglib/rfc7895/SimpleStrategy.java b/yanglib/mdsal-yanglib-rfc7895/src/main/java/org/opendaylight/mdsal/yanglib/rfc7895/SimpleStrategy.java
deleted file mode 100644 (file)
index 97a2deb..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.yanglib.rfc7895;
-
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
-
-final class SimpleStrategy implements ClassLoadingStrategy {
-    static final SimpleStrategy INSTANCE = new SimpleStrategy();
-
-    @Override
-    public Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
-        return SimpleStrategy.class.getClassLoader().loadClass(fullyQualifiedName);
-    }
-}
index 8aa3402cdd788c8ad0813d3d5982f1c5d22bd760..0e92b6ec17b25a56d70a3989e06d8b17522aac50 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.mdsal.yanglib.rfc7895;
 import static com.google.common.base.Verify.verifyNotNull;
 
 import com.google.common.annotations.Beta;
-import com.google.common.collect.Collections2;
 import java.io.IOException;
+import java.util.List;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -20,6 +20,8 @@ import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
 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.runtime.spi.ModuleInfoSnapshotBuilder;
 import org.opendaylight.mdsal.yanglib.api.SchemaContextResolver;
 import org.opendaylight.mdsal.yanglib.api.YangLibSupport;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.$YangModuleInfoImpl;
@@ -27,13 +29,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.librar
 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContextFactory;
 import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 
 @Beta
 @NonNullByDefault
@@ -45,15 +43,13 @@ public final class YangModuleLibrarySupport implements YangLibSupport {
     @Inject
     public YangModuleLibrarySupport(final YangParserFactory parserFactory, final BindingRuntimeGenerator generator,
             final BindingCodecTreeFactory codecFactory) throws YangParserException, IOException {
-        final YangModuleInfo yangLibModule = $YangModuleInfoImpl.getInstance();
+        final ModuleInfoSnapshotBuilder builder = new ModuleInfoSnapshotBuilder("yanglib", parserFactory);
+        builder.registerModuleInfos(List.of($YangModuleInfoImpl.getInstance()));
+        final ModuleInfoSnapshot snapshot = builder.build();
+        context = snapshot.getEffectiveModelContext();
 
-        context = parserFactory.createParser()
-                .addLibSources(Collections2.transform(yangLibModule.getImportedModules(),
-                    YangModuleLibrarySupport::createSource))
-                .addSource(createSource(yangLibModule))
-                .buildEffectiveModel();
-        final BindingCodecTree codecTree = codecFactory.create(DefaultBindingRuntimeContext.create(
-            generator.generateTypeMapping(context), SimpleStrategy.INSTANCE));
+        final BindingCodecTree codecTree = codecFactory.create(new DefaultBindingRuntimeContext(
+            generator.generateTypeMapping(context), snapshot));
 
         this.codec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(ModulesState.class)));
     }
@@ -63,10 +59,4 @@ public final class YangModuleLibrarySupport implements YangLibSupport {
             final SchemaContextResolver resolver) {
         return new MountPointContextFactoryImpl(mountId, resolver, context, codec);
     }
-
-    private static YangTextSchemaSource createSource(final YangModuleInfo info) {
-        final QName name = info.getName();
-        return YangTextSchemaSource.delegateForByteSource(
-            RevisionSourceIdentifier.create(name.getLocalName(), name.getRevision()), info.getYangTextByteSource());
-    }
 }
index 354b2b5340ea1aebebc45d8265043e8a6c4840b9..5e8d07850ae3d681c5495f23b451ea1ea57df2e9 100644 (file)
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding-runtime-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-runtime-spi</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>mdsal-binding-dom-codec-api</artifactId>
diff --git a/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/SimpleStrategy.java b/yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/SimpleStrategy.java
deleted file mode 100644 (file)
index 9e8cedc..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.yanglib.rfc8525;
-
-import org.opendaylight.mdsal.binding.runtime.api.ClassLoadingStrategy;
-
-final class SimpleStrategy implements ClassLoadingStrategy {
-    static final SimpleStrategy INSTANCE = new SimpleStrategy();
-
-    @Override
-    public Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
-        return SimpleStrategy.class.getClassLoader().loadClass(fullyQualifiedName);
-    }
-}
index 78654c78d504127fdfe25a398e96441ee07c78c9..4da1e6b377da7f162704fd95f48f53e156441000 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.mdsal.yanglib.rfc8525;
 import static com.google.common.base.Verify.verifyNotNull;
 
 import com.google.common.annotations.Beta;
-import com.google.common.collect.Collections2;
 import java.io.IOException;
+import java.util.List;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -21,6 +21,8 @@ import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNo
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingIdentityCodec;
 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.runtime.spi.ModuleInfoSnapshotBuilder;
 import org.opendaylight.mdsal.yanglib.api.SchemaContextResolver;
 import org.opendaylight.mdsal.yanglib.api.YangLibSupport;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.$YangModuleInfoImpl;
@@ -29,13 +31,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.librar
 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContextFactory;
 import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 
 @Beta
 @NonNullByDefault
@@ -50,15 +48,13 @@ public final class YangLibrarySupport implements YangLibSupport {
     @Inject
     public YangLibrarySupport(final YangParserFactory parserFactory, final BindingRuntimeGenerator generator,
             final BindingCodecTreeFactory codecFactory) throws YangParserException, IOException {
-        final YangModuleInfo yangLibModule = $YangModuleInfoImpl.getInstance();
+        final ModuleInfoSnapshotBuilder builder = new ModuleInfoSnapshotBuilder("yanglib", parserFactory);
+        builder.registerModuleInfos(List.of($YangModuleInfoImpl.getInstance()));
+        final ModuleInfoSnapshot snapshot = builder.build();
+        context = snapshot.getEffectiveModelContext();
 
-        context = parserFactory.createParser()
-                .addLibSources(Collections2.transform(yangLibModule.getImportedModules(),
-                    YangLibrarySupport::createSource))
-                .addSource(createSource(yangLibModule))
-                .buildEffectiveModel();
-        final BindingCodecTree codecTree = codecFactory.create(DefaultBindingRuntimeContext.create(
-            generator.generateTypeMapping(context), SimpleStrategy.INSTANCE));
+        final BindingCodecTree codecTree = codecFactory.create(new DefaultBindingRuntimeContext(
+            generator.generateTypeMapping(context), snapshot));
 
         this.identityCodec = codecTree.getIdentityCodec();
         this.codec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(YangLibrary.class)));
@@ -70,10 +66,4 @@ public final class YangLibrarySupport implements YangLibSupport {
             final SchemaContextResolver resolver) {
         return new MountPointContextFactoryImpl(mountId, resolver, context, identityCodec, codec, legacyCodec);
     }
-
-    private static YangTextSchemaSource createSource(final YangModuleInfo info) {
-        final QName name = info.getName();
-        return YangTextSchemaSource.delegateForByteSource(
-            RevisionSourceIdentifier.create(name.getLocalName(), name.getRevision()), info.getYangTextByteSource());
-    }
 }