package io.vertx.servicediscovery.utils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
public class ClassLoaderUtils {
private static final ClassLoader CURRENT = ClassLoaderUtils.class.getClassLoader();
public static <T> Class<T> load(String className, ClassLoader classLoader) {
Objects.requireNonNull(className);
Class<T> loaded = tryToLoad(className, CURRENT);
if (loaded == null && classLoader != null) {
return tryToLoad(className, classLoader);
}
if (loaded == null && Thread.currentThread().getContextClassLoader() != null) {
return tryToLoad(className, Thread.currentThread().getContextClassLoader());
}
return loaded;
}
private static <T> Class<T> tryToLoad(String className, ClassLoader classLoader) {
try {
return (Class<T>) classLoader.loadClass(className);
} catch (ClassNotFoundException e) {
return null;
}
}
public static <X, T> X createWithDelegate(Class<X> x, T svc) {
try {
Optional<Constructor<?>> maybe = Arrays.stream(x.getConstructors())
.filter(c -> c.getParameterCount() == 1)
.filter(c -> c.getParameterTypes()[0].isAssignableFrom(svc.getClass()))
.findFirst();
if (maybe.isPresent()) {
return (X) maybe.get().newInstance(svc);
} else {
return null;
}
} catch (Exception e) {
return null;
}
}
public static Object (Object object) {
if (object == null) {
return null;
}
if (object.getClass().getName().equals("jdk.nashorn.api.scripting.ScriptObjectMirror")) {
return extractDelegateFromJsObject(object);
}
if (object.getClass().getName().startsWith("org.jruby.RubyObjectVar")) {
return extractDelegateFromJRubyObject(object);
}
return extractDelegateFromRX(object);
}
private static Object (Object object) {
try {
Method method = object.getClass().getMethod("getDelegate");
return method.invoke(object);
} catch (NoSuchMethodException e) {
return null;
} catch (Exception e) {
throw new RuntimeException("Unable to extract the delegate from the given RX object", e);
}
}
public static Object (Object object) {
try {
Method method = object.getClass().getMethod("callMethod", String.class);
return method.invoke(object, "j_del");
} catch (Exception e) {
throw new RuntimeException("Unable to extract the delegate from the given Ruby object", e);
}
}
public static Object (Object object) {
try {
Method method = object.getClass().getMethod("getMember", String.class);
return method.invoke(object, "_jdel");
} catch (Exception e) {
throw new RuntimeException("Unable to extract the delegate from the given JavaScript object", e);
}
}
}