2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.binding.dom.codec.loader;
10 import static com.google.common.base.Verify.verify;
11 import static com.google.common.base.Verify.verifyNotNull;
13 import com.google.common.annotations.Beta;
14 import java.security.AccessController;
15 import java.security.PrivilegedAction;
16 import javassist.ClassPool;
17 import javassist.CtClass;
18 import javassist.LoaderClassPath;
19 import javassist.NotFoundException;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.yangtools.yang.binding.DataContainer;
24 * Static class pool, bound to the class loader of binding-dom-codec. It can be used to acquire CtClass instances that
25 * reside within the binding-dom-codec artifact or any of its direct mandatory dependencies. It can also instantiate
26 * {@link CodecClassLoader} instances for use with code generation.
28 * @author Robert Varga
31 public final class StaticClassPool {
32 static final ClassLoader LOADER = verifyNotNull(StaticClassPool.class.getClassLoader());
33 static final ClassPool POOL;
36 final ClassPool pool = new ClassPool();
37 pool.appendClassPath(new LoaderClassPath(LOADER));
41 private StaticClassPool() {
46 * Instantiate a new CodecClassLoader.
48 * @return A new CodecClassLoader.
50 public static @NonNull CodecClassLoader createLoader() {
51 return AccessController.doPrivileged((PrivilegedAction<CodecClassLoader>)() -> new RootCodecClassLoader());
55 * Resolve a binding-dom-codec class to its {@link CtClass} counterpart.
57 * @param clazz Class to resolve
58 * @return A CtClass instance
59 * @throws IllegalStateException if the class cannot be resolved
60 * @throws NullPointerException if {@code clazz} is null
62 public static synchronized @NonNull CtClass findClass(final @NonNull Class<?> clazz) {
65 ret = POOL.get(clazz.getName());
66 } catch (NotFoundException e) {
67 throw new IllegalStateException("Failed to find " + clazz, e);
73 // Sanity check: target has to resolve yang-binding contents to the same class, otherwise we are in a pickle
74 static void verifyStaticLinkage(final ClassLoader candidate) {
75 final Class<?> targetClazz;
77 targetClazz = candidate.loadClass(DataContainer.class.getName());
78 } catch (ClassNotFoundException e) {
79 throw new IllegalStateException("ClassLoader " + candidate + " cannot load " + DataContainer.class, e);
81 verify(DataContainer.class.equals(targetClazz),
82 "Class mismatch on DataContainer. Ours is from %s, target %s has %s from %s",
83 DataContainer.class.getClassLoader(), candidate, targetClazz, targetClazz.getClassLoader());