This is an automated email from the ASF dual-hosted git repository.

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 1431a1b  [converter] handle default methods
     new 0cb4bb0  Merge pull request #10 from stbischof/conv_def_method
1431a1b is described below

commit 1431a1bb2262cb60e6c072b49930f2f54e216e02
Author: Stefan Bischof <stbisc...@bipolis.org>
AuthorDate: Wed Mar 18 19:14:39 2020 +0100

    [converter] handle default methods
---
 .../org/osgi/util/converter/ConvertingImpl.java    | 29 ++++++++++++++++++++++
 .../org/osgi/util/converter/ConverterTest.java     |  8 ++++++
 .../util/converter/InterfaceWithDefaultMethod.java | 11 ++++++++
 3 files changed, 48 insertions(+)

diff --git 
a/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java 
b/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java
index c9e3722..0733060 100644
--- 
a/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java
+++ 
b/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java
@@ -17,6 +17,9 @@
 package org.osgi.util.converter;
 
 import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -810,6 +813,32 @@ class ConvertingImpl extends AbstractSpecifying<Converting>
                                        if (cls.isAnnotation()) {
                                                val = method.getDefaultValue();
                                        }
+                                       else if (method.isDefault())
+                                       {
+                                               double javaVersion = 
Double.parseDouble(
+                                                       
System.getProperty("java.class.version"));
+                                               double java8 = 52.0;
+                                               if (javaVersion > java8)
+                                               {
+                                                       val = 
MethodHandles.lookup().findSpecial(
+                                                               
method.getDeclaringClass(), method.getName(),
+                                                               
MethodType.methodType(method.getReturnType(),
+                                                                       new 
Class[] {}),
+                                                               
method.getDeclaringClass()).bindTo(
+                                                                       
proxy).invokeWithArguments(args);
+                                               }
+                                               else
+                                               {
+                                                       Constructor<Lookup> c = 
Lookup.class.getDeclaredConstructor(
+                                                               Class.class);
+                                                       if (!c.isAccessible())
+                                                       {
+                                                               
c.setAccessible(true);
+                                                       }
+                                                       val = 
c.newInstance(cls).in(cls).unreflectSpecial(method,
+                                                               
cls).bindTo(proxy).invokeWithArguments(args);
+                                               }
+                                       }
 
                                        if (val == null) {
                                                if (args != null && args.length 
== 1) {
diff --git 
a/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java 
b/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java
index ef00c13..166b9c9 100644
--- 
a/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java
+++ 
b/converter/converter/src/test/java/org/osgi/util/converter/ConverterTest.java
@@ -1465,6 +1465,14 @@ public class ConverterTest {
         assertNotNull(k);
     }
 
+    @Test
+    public void testDefaultInterfaceMethod() throws Throwable
+    {
+        Class<?> clazz = InterfaceWithDefaultMethod.class;
+        InterfaceWithDefaultMethod i = (InterfaceWithDefaultMethod) 
Converters.standardConverter().convert(
+            new HashMap<String, Object>()).to(clazz);
+        assertEquals(InterfaceWithDefaultMethod.RESULT, i.defaultMethod());
+    }
     static interface MyIntf2 {
         String code();
         Integer value();
diff --git 
a/converter/converter/src/test/java/org/osgi/util/converter/InterfaceWithDefaultMethod.java
 
b/converter/converter/src/test/java/org/osgi/util/converter/InterfaceWithDefaultMethod.java
new file mode 100644
index 0000000..c8a42ff
--- /dev/null
+++ 
b/converter/converter/src/test/java/org/osgi/util/converter/InterfaceWithDefaultMethod.java
@@ -0,0 +1,11 @@
+package org.osgi.util.converter;
+
+public interface InterfaceWithDefaultMethod
+{
+    public static final String RESULT = "r";
+
+    public default String defaultMethod()
+    {
+        return RESULT;
+    }
+}
\ No newline at end of file

Reply via email to