package jalse.entities.functions;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import jalse.entities.DefaultEntityProxyFactory;
import jalse.entities.methods.DefaultMethod;
/**
* This is a method function for {@code default} methods. It will resolve an {@link DefaultMethod}
* to be used by the entity typing system.<br>
* <br>
*
* @author Elliot Ford
*
* @see DefaultEntityProxyFactory
*
*/
public class DefaultFunction implements EntityMethodFunction {
private static final Constructor<Lookup> LOOKUP_CONSTRUCTOR;
static {
try {
LOOKUP_CONSTRUCTOR = Lookup.class.getDeclaredConstructor(Class.class, int.class);
LOOKUP_CONSTRUCTOR.setAccessible(true);
} catch (final Exception e) {
throw new Error("Could not get private Lookup constructor instance", e);
}
}
@Override
public DefaultMethod apply(final Method m) {
// Check default
if (!m.isDefault()) {
return null;
}
final Class<?> declaringClazz = m.getDeclaringClass();
// Create lookup
Lookup lookup;
try {
lookup = LOOKUP_CONSTRUCTOR.newInstance(m.getDeclaringClass(), Lookup.PRIVATE);
} catch (ReflectiveOperationException | IllegalArgumentException e) {
throw new RuntimeException(e);
}
// Get handle
MethodHandle handle;
try {
handle = lookup.unreflectSpecial(m, declaringClazz);
} catch (final IllegalAccessException e) {
throw new RuntimeException(e);
}
// Create default method
return new DefaultMethod(handle, m.getParameterCount());
}
}