*/
package org.opendaylight.mdsal.binding.generator.util;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
import javassist.ClassPath;
import javassist.ClassPool;
import javassist.CtClass;
-import javassist.CtField;
import javassist.LoaderClassPath;
-import javassist.Modifier;
import javassist.NotFoundException;
import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.ThreadSafe;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* Users of this utility class are expected to synchronize on this instance
* it they need to ensure atomic operations on it.
*/
+@NonNullByDefault
+@ThreadSafe
public final class JavassistUtils {
private static final Logger LOG = LoggerFactory.getLogger(JavassistUtils.class);
private static final Map<ClassPool, JavassistUtils> INSTANCES = new WeakHashMap<>();
+ @GuardedBy("this")
private final Map<ClassLoader, ClassPath> loaderClassPaths = new WeakHashMap<>();
+ @GuardedBy("this")
private final ClassPool classPool;
private JavassistUtils(final ClassPool pool) {
* @return shared utility instance for specified pool
*/
public static synchronized JavassistUtils forClassPool(final ClassPool pool) {
- JavassistUtils ret = INSTANCES.get(requireNonNull(pool));
- if (ret == null) {
- ret = new JavassistUtils(pool);
- INSTANCES.put(pool, ret);
- }
- return ret;
- }
-
- public CtClass createClass(final String fqn, final ClassGenerator cls) throws CannotCompileException {
- CtClass target = classPool.makeClass(fqn);
- cls.process(target);
- return target;
- }
-
- public CtClass createClass(final String fqn, final CtClass superInterface, final ClassGenerator cls)
- throws CannotCompileException {
- CtClass target = classPool.makeClass(fqn);
- implementsType(target, superInterface);
- cls.process(target);
- return target;
+ return INSTANCES.computeIfAbsent(requireNonNull(pool), JavassistUtils::new);
}
/**
return result;
}
- private static void implementsType(final CtClass it, final CtClass supertype) {
- checkArgument(supertype.isInterface(), "Supertype %s is not an interface", supertype);
- it.addInterface(supertype);
- }
-
@GuardedBy("this")
- public CtClass asCtClass(final Class<?> class1) {
- return get(this.classPool, class1);
- }
-
- public CtField field(final CtClass it, final String name, final Class<?> returnValue) throws CannotCompileException {
- final CtField field = new CtField(asCtClass(returnValue), name, it);
- field.setModifiers(Modifier.PUBLIC);
- it.addField(field);
- return field;
- }
-
- public CtField staticField(final CtClass it, final String name, final Class<?> returnValue) throws CannotCompileException {
- return staticField(it, name, returnValue, null);
- }
-
- public CtField staticField(final CtClass it, final String name,
- final Class<?> returnValue,
- final SourceCodeGenerator sourceGenerator) throws CannotCompileException {
- final CtField field = new CtField(asCtClass(returnValue), name, it);
- field.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
- it.addField(field);
-
- if (sourceGenerator != null) {
- sourceGenerator.appendField(field, null);
- }
-
- return field;
- }
-
- public CtClass get(final ClassPool pool, final Class<? extends Object> cls) {
+ public CtClass asCtClass(final Class<?> cls) {
try {
- return pool.get(cls.getName());
+ return classPool.get(cls.getName());
} catch (NotFoundException nfe1) {
appendClassLoaderIfMissing(cls.getClassLoader());
try {
- return pool.get(cls.getName());
+ return classPool.get(cls.getName());
} catch (final NotFoundException nfe2) {
LOG.warn("Appending ClassClassPath for {}", cls, nfe2);
- pool.appendClassPath(new ClassClassPath(cls));
+ classPool.appendClassPath(new ClassClassPath(cls));
try {
- return pool.get(cls.getName());
+ return classPool.get(cls.getName());
} catch (NotFoundException e) {
- LOG.warn("Failed to load class {} from pool {}", cls, pool, e);
+ LOG.warn("Failed to load class {} from pool {}", cls, classPool, e);
throw new IllegalStateException("Failed to load class", e);
}
}
loaderClassPaths.put(loader, ctLoader);
}
}
-
- public void ensureClassLoader(final Class<?> child) {
- appendClassLoaderIfMissing(child.getClassLoader());
- }
}