Hi all,

after reading http://benjiweber.co.uk/blog/2015/08/04/lambda-type-references/ I went ahead and let LambdaModel implement IObjectClassAwareModel.

Let this idea sink in and then we can discuss whether we want to have this 'hack' in core.

Have fun
Sven


-------- Forwarded Message --------
Subject:        wicket git commit: LambdaModel trick to get the object class
Date:   Wed, 29 Jun 2016 19:01:18 +0000 (UTC)
From:   svenme...@apache.org
Reply-To:       dev@wicket.apache.org
To:     comm...@wicket.apache.org



Repository: wicket
Updated Branches:
  refs/heads/lambdas-objectclass [created] ab7134388


LambdaModel trick to get the object class


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/ab713438
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/ab713438
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/ab713438

Branch: refs/heads/lambdas-objectclass
Commit: ab7134388cf80ffd96f3c930afa9f228e736d9ff
Parents: 739bab4
Author: Sven Meier <svenme...@apache.org>
Authored: Wed Jun 29 20:02:57 2016 +0200
Committer: Sven Meier <svenme...@apache.org>
Committed: Wed Jun 29 21:00:48 2016 +0200

----------------------------------------------------------------------
 .../org/apache/wicket/model/LambdaModel.java    | 53 +++++++++++++++++++-
 .../apache/wicket/model/LambdaModelTest.java    |  2 +
 2 files changed, 54 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/ab713438/wicket-core/src/main/java/org/apache/wicket/model/LambdaModel.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/model/LambdaModel.java 
b/wicket-core/src/main/java/org/apache/wicket/model/LambdaModel.java
index 3266992..7b7eef2 100644
--- a/wicket-core/src/main/java/org/apache/wicket/model/LambdaModel.java
+++ b/wicket-core/src/main/java/org/apache/wicket/model/LambdaModel.java
@@ -16,6 +16,9 @@
  */
 package org.apache.wicket.model;
+import java.lang.invoke.SerializedLambda;
+import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.Objects;
import org.apache.wicket.lambda.WicketBiConsumer;
@@ -33,7 +36,7 @@ import org.apache.wicket.util.lang.Args;
  *
  * @param <T> The type of the Model Object
  */
-public class LambdaModel<T> implements IModel<T>
+public class LambdaModel<T> implements IObjectClassAwareModel<T>
 {
        private static final long serialVersionUID = 1L;
@@ -66,6 +69,12 @@ public class LambdaModel<T> implements IModel<T>
        }
@Override
+       public Class<T> getObjectClass()
+       {
+               return getReturnType(getter);
+       }
+
+       @Override
        public int hashCode()
        {
                return org.apache.wicket.util.lang.Objects.hashCode(getter, 
setter);
@@ -151,6 +160,12 @@ public class LambdaModel<T> implements IModel<T>
                        private static final long serialVersionUID = 1L;
@Override
+                       public Class<T> getObjectClass()
+                       {
+                               return getReturnType(getter);
+                       }
+
+                       @Override
                        public void detach() {
                                target.detach();
                        }
@@ -202,9 +217,45 @@ public class LambdaModel<T> implements IModel<T>
                        private static final long serialVersionUID = 1L;
@Override
+                       public Class<T> getObjectClass()
+                       {
+                               return getReturnType(getter);
+                       }
+
+                       @Override
                        public void detach() {
                                target.detach();
                        }
                };
        }
+
+       /**
+        * Get the return type of a {@link WicketSupplier} or {@link 
WicketFunction}.
+        *
+        * @param lambda
+        * @return return type or {@code null}
+        *
+        * @see http://benjiweber.co.uk/blog/2015/08/04/lambda-type-references/
+        */
+       @SuppressWarnings("unchecked")
+       static <T> Class<T> getReturnType(Object lambda)
+       {
+               try
+               {
+                       Method replaceMethod = 
lambda.getClass().getDeclaredMethod("writeReplace");
+                       replaceMethod.setAccessible(true);
+
+                       SerializedLambda serialized = 
(SerializedLambda)replaceMethod.invoke(lambda);
+
+                       Class<?> implClass = 
Class.forName(serialized.getImplClass().replaceAll("/", "."));
+
+                       return 
(Class<T>)Arrays.asList(implClass.getDeclaredMethods()).stream()
+                               .filter(method -> 
Objects.equals(method.getName(), serialized.getImplMethodName()))
+                               .findFirst().get().getReturnType();
+               }
+               catch (Exception e)
+               {
+                       return null;
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/ab713438/wicket-core/src/test/java/org/apache/wicket/model/LambdaModelTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/model/LambdaModelTest.java 
b/wicket-core/src/test/java/org/apache/wicket/model/LambdaModelTest.java
index 8bb31ff..576f4b6 100644
--- a/wicket-core/src/test/java/org/apache/wicket/model/LambdaModelTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/model/LambdaModelTest.java
@@ -111,6 +111,8 @@ public class LambdaModelTest
                personNameModel.setObject(personName);
                assertThat(personNameModel.getObject(), is(personName));
+ assertEquals(String.class, ((IObjectClassAwareModel<?>)personNameModel).getObjectClass());
+
                serialize(personNameModel, personName);
        }


Reply via email to