package org.orienteer.core.dao.handler;

import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.Optional;

import org.joor.Reflect;
import org.orienteer.core.dao.IMethodHandler;

/**
 * {@link IMethodHandler} which invoke interfaces default method implementations
 * @param <T> type of target/delegate object
 */
public class DefaultInterfaceMethodHandler<T> implements IMethodHandler<T> {

	@Override
	public Optional<Object> handle(T target, Object proxy, Method method, Object[] args, InvocationChain<T> chain) throws Throwable {
		if(method.isDefault()) {
		Class<?> declaringClass = method.getDeclaringClass();
		MethodHandles.Lookup lookup = Reflect.onClass(MethodHandles.Lookup.class)
				.create(declaringClass, MethodHandles.Lookup.PRIVATE).get();
		return Optional.ofNullable(lookup.unreflectSpecial(method, declaringClass)
									  .bindTo(proxy)
									  .invokeWithArguments(args));
		} else return chain.handle(target, proxy, method, args);
	}

}

@@ -34,16 +34,56 @@
 ndler;%0A%0A
+import java.lang.annotation.Annotation;%0A
 import j
@@ -604,35 +604,8 @@
 e %7B%0A
-%09%09if(method.isDefault()) %7B%0A
 %09%09Cl
@@ -656,16 +656,44 @@
 lass();%0A
+%09%09if(method.isDefault()) %7B%0A%09
 %09%09Method
@@ -764,16 +764,17 @@
 ss)%0A%09%09%09%09
+%09
 .create(
@@ -826,16 +826,17 @@
 .get();%0A
+%09
 %09%09return
@@ -913,16 +913,17 @@
 %09%09%09%09%09%09%09%09
+%09
   .bindT
@@ -931,16 +931,17 @@
 (proxy)%0A
+%09
 %09%09%09%09%09%09%09%09
@@ -981,16 +981,269 @@
 %09%7D else 
+if(proxy instanceof Annotation%0A%09%09%09%09%09%09&& (args==null %7C%7C args.length==0)%0A%09%09%09%09%09%09&& !method.getDeclaringClass().equals(Annotation.class)) %7B%0A%09%09%09Object defaultValue = method.getDefaultValue();%0A%09%09%09if(defaultValue!=null) return Optional.of(defaultValue);%0A%09%09%7D%0A%09%09
 return c

Support of DAO'ing of Annotations