[#5442] Support default methods in DefaultRecordMapper.ProxyMapper
This commit is contained in:
parent
2ae8460ef0
commit
e7b3740a4b
@ -55,6 +55,7 @@ import static org.jooq.impl.Tools.hasColumnAnnotations;
|
||||
import static org.jooq.tools.reflect.Reflect.accessible;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
@ -423,12 +424,15 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
*/
|
||||
private class ProxyMapper implements RecordMapper<R, E> {
|
||||
|
||||
Constructor<Lookup> constructor;
|
||||
|
||||
@Override
|
||||
public final E map(R record) {
|
||||
return new MutablePOJOMapper(null, proxy()).map(record);
|
||||
}
|
||||
|
||||
private E proxy() {
|
||||
final Object[] result = new Object[1];
|
||||
final Map<String, Object> map = new HashMap<String, Object>();
|
||||
final InvocationHandler handler = new InvocationHandler() {
|
||||
|
||||
@ -439,22 +443,38 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
|
||||
int length = (args == null ? 0 : args.length);
|
||||
|
||||
if (length == 0 && name.startsWith("get")) {
|
||||
if (length == 0 && name.startsWith("get"))
|
||||
return map.get(name.substring(3));
|
||||
}
|
||||
else if (length == 0 && name.startsWith("is")) {
|
||||
else if (length == 0 && name.startsWith("is"))
|
||||
return map.get(name.substring(2));
|
||||
}
|
||||
else if (length == 1 && name.startsWith("set")) {
|
||||
else if (length == 1 && name.startsWith("set"))
|
||||
map.put(name.substring(3), args[0]);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// [#5442] Default methods should be invoked to run client implementation
|
||||
else if (method.isDefault())
|
||||
try {
|
||||
if (constructor == null)
|
||||
constructor = accessible(Lookup.class.getDeclaredConstructor(Class.class, int.class));
|
||||
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
return constructor
|
||||
.newInstance(declaringClass, Lookup.PRIVATE)
|
||||
.unreflectSpecial(method, declaringClass)
|
||||
.bindTo(result[0])
|
||||
.invokeWithArguments(args);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new MappingException("Cannot invoke default method", e);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (E) Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, handler);
|
||||
result[0] = Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, handler);
|
||||
return (E) result[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user