Split out mdsal-binding-loader
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / loader / RootCodecClassLoader.java
diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/loader/RootCodecClassLoader.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/loader/RootCodecClassLoader.java
deleted file mode 100644 (file)
index b52fe17..0000000
+++ /dev/null
@@ -1,118 +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.binding.dom.codec.impl.loader;
-
-import static com.google.common.base.Verify.verify;
-import static com.google.common.base.Verify.verifyNotNull;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-// A root codec classloader, binding only whatever is available StaticClassPool
-final class RootCodecClassLoader extends CodecClassLoader {
-    private static final Logger LOG = LoggerFactory.getLogger(RootCodecClassLoader.class);
-    private static final ClassLoader LOADER = verifyNotNull(RootCodecClassLoader.class.getClassLoader());
-
-    static {
-        verify(registerAsParallelCapable());
-    }
-
-    @SuppressWarnings("rawtypes")
-    private static final AtomicReferenceFieldUpdater<RootCodecClassLoader, ImmutableMap> LOADERS_UPDATER =
-            AtomicReferenceFieldUpdater.newUpdater(RootCodecClassLoader.class, ImmutableMap.class, "loaders");
-
-    private volatile ImmutableMap<ClassLoader, CodecClassLoader> loaders = ImmutableMap.of();
-
-    RootCodecClassLoader() {
-        super(LOADER);
-    }
-
-    @Override
-    CodecClassLoader findClassLoader(final Class<?> bindingClass) {
-        final ClassLoader target = bindingClass.getClassLoader();
-        if (target == null) {
-            // No class loader associated ... well, let's use root then
-            return this;
-        }
-
-        // Cache for update
-        ImmutableMap<ClassLoader, CodecClassLoader> local = loaders;
-        final CodecClassLoader known = local.get(target);
-        if (known != null) {
-            return known;
-        }
-
-        // Alright, we need to determine if the class is accessible through our hierarchy (in which case we use
-        // ourselves) or we need to create a new Leaf.
-        final CodecClassLoader found;
-        if (!isOurClass(bindingClass)) {
-            verifyStaticLinkage(target);
-            found = AccessController.doPrivileged(
-                (PrivilegedAction<CodecClassLoader>)() -> new LeafCodecClassLoader(this, target));
-        } else {
-            found = this;
-        }
-
-        // Now make sure we cache this result
-        while (true) {
-            final Builder<ClassLoader, CodecClassLoader> builder = ImmutableMap.builderWithExpectedSize(
-                local.size() + 1);
-            builder.putAll(local);
-            builder.put(target, found);
-
-            if (LOADERS_UPDATER.compareAndSet(this, local, builder.build())) {
-                return found;
-            }
-
-            local = loaders;
-            final CodecClassLoader recheck = local.get(target);
-            if (recheck != null) {
-                return recheck;
-            }
-        }
-    }
-
-    @Override
-    void appendLoaders(final Set<LeafCodecClassLoader> newLoaders) {
-        // Root loader should never see the requirement for other loaders, as that would violate loop-free nature
-        // of generated code: if a binding class is hosted in root loader, all its references must be visible from
-        // the root loader and hence all the generated code ends up residing in the root loader, too.
-        throw new IllegalStateException("Attempted to extend root loader with " + newLoaders);
-    }
-
-    private boolean isOurClass(final Class<?> bindingClass) {
-        final Class<?> ourClass;
-        try {
-            ourClass = loadClass(bindingClass.getName(), false);
-        } catch (ClassNotFoundException e) {
-            LOG.debug("Failed to load {}", bindingClass, e);
-            return false;
-        }
-        return bindingClass.equals(ourClass);
-    }
-
-    // Sanity check: target has to resolve yang-binding contents to the same class, otherwise we are in a pickle
-    private static void verifyStaticLinkage(final ClassLoader candidate) {
-        final Class<?> targetClazz;
-        try {
-            targetClazz = candidate.loadClass(DataContainer.class.getName());
-        } catch (ClassNotFoundException e) {
-            throw new IllegalStateException("ClassLoader " + candidate + " cannot load " + DataContainer.class, e);
-        }
-        verify(DataContainer.class.equals(targetClazz),
-            "Class mismatch on DataContainer. Ours is from %s, target %s has %s from %s",
-            DataContainer.class.getClassLoader(), candidate, targetClazz, targetClazz.getClassLoader());
-    }
-}