You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2020/04/13 10:31:58 UTC

[myfaces] branch master updated: MYFACES-4327 lazy construct bean properties, probably most of the time only a 50% are used in the view

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

tandraschko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f606f7  MYFACES-4327 lazy construct bean properties, probably most of the time only a 50% are used in the view
3f606f7 is described below

commit 3f606f78536430d1502a341dcc5b307fcf925890
Author: Thomas Andraschko <ta...@apache.org>
AuthorDate: Mon Apr 13 12:31:36 2020 +0200

    MYFACES-4327 lazy construct bean properties, probably most of the time only a 50% are used in the view
---
 .../el/resolver/MethodHandleBeanELResolver.java    |  9 ++-
 .../myfaces/util/lang/MethodHandleUtils.java       | 89 +++++++++++++++-------
 2 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/impl/src/main/java/org/apache/myfaces/el/resolver/MethodHandleBeanELResolver.java b/impl/src/main/java/org/apache/myfaces/el/resolver/MethodHandleBeanELResolver.java
index 6588d0e..b69959f 100644
--- a/impl/src/main/java/org/apache/myfaces/el/resolver/MethodHandleBeanELResolver.java
+++ b/impl/src/main/java/org/apache/myfaces/el/resolver/MethodHandleBeanELResolver.java
@@ -130,8 +130,11 @@ public class MethodHandleBeanELResolver extends BeanELResolver
     protected MethodHandleUtils.LambdaPropertyDescriptor getPropertyDescriptor(Object base, Object property)
     {
         Map<String, MethodHandleUtils.LambdaPropertyDescriptor> beanCache = cache.computeIfAbsent(
-                base.getClass().getName(), k -> MethodHandleUtils.getLambdaPropertyDescriptors(base.getClass()));
-        return beanCache.get((String) property);
-    }
+                base.getClass().getName(),
+                k -> new ConcurrentHashMap<>());
 
+        return beanCache.computeIfAbsent(
+                (String) property,
+                k -> MethodHandleUtils.getLambdaPropertyDescriptor(base.getClass(), k));
+    }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/util/lang/MethodHandleUtils.java b/impl/src/main/java/org/apache/myfaces/util/lang/MethodHandleUtils.java
index 7152823..de474f8 100644
--- a/impl/src/main/java/org/apache/myfaces/util/lang/MethodHandleUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/util/lang/MethodHandleUtils.java
@@ -35,9 +35,9 @@ import java.util.function.Function;
 import java.util.function.ObjDoubleConsumer;
 import java.util.function.ObjIntConsumer;
 import java.util.function.ObjLongConsumer;
-import javax.el.ELException;
+import javax.faces.FacesException;
 
-public class MethodHandleUtils
+public final class MethodHandleUtils
 {
     private static Method privateLookupIn;
 
@@ -80,10 +80,67 @@ public class MethodHandleUtils
         }
     }
 
+    public static LambdaPropertyDescriptor getLambdaPropertyDescriptor(Class<?> target, String name)
+    {
+        try
+        {
+            PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
+            if (propertyDescriptors == null || propertyDescriptors.length == 0)
+            {
+                return null;
+            }
+            
+            for (PropertyDescriptor pd : propertyDescriptors)
+            {
+                if (name.equals(pd.getName()))
+                {
+                    MethodHandles.Lookup lookup = (MethodHandles.Lookup) privateLookupIn.invoke(null, target,
+                            MethodHandles.lookup());
+                    return createLambdaPropertyDescriptor(pd, lookup);
+                }
+            }
+
+            throw new FacesException("Property \"" + name + "\" not found on \"" + target.getName() + "\"");
+        }
+        catch (Throwable e)
+        {
+            throw new FacesException(e);
+        }
+    }
+    
+    public static LambdaPropertyDescriptor createLambdaPropertyDescriptor(PropertyDescriptor pd,
+            MethodHandles.Lookup lookup) throws Throwable
+    {
+        LambdaPropertyDescriptor lpd = new LambdaPropertyDescriptor();
+        lpd.wrapped = pd;
+
+        Method readMethod = pd.getReadMethod();
+        if (readMethod != null)
+        {
+            MethodHandle handle = lookup.unreflect(readMethod);
+            CallSite callSite = LambdaMetafactory.metafactory(lookup,
+                    "apply",
+                    MethodType.methodType(Function.class),
+                    MethodType.methodType(Object.class, Object.class),
+                    handle,
+                    handle.type());
+            lpd.readFunction = (Function) callSite.getTarget().invokeExact();
+        }
+
+        Method writeMethod = pd.getWriteMethod();
+        if (writeMethod != null)
+        {
+            MethodHandle handle = lookup.unreflect(writeMethod);
+            lpd.writeFunction = createSetter(lookup, lpd, handle);
+        }
+
+        return lpd;
+    }
+    
     public static Map<String, LambdaPropertyDescriptor> getLambdaPropertyDescriptors(Class<?> target)
     {
         try
-        {            
+        {
             PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
             if (propertyDescriptors == null || propertyDescriptors.length == 0)
             {
@@ -97,29 +154,7 @@ public class MethodHandleUtils
             
             for (PropertyDescriptor pd : Introspector.getBeanInfo(target).getPropertyDescriptors())
             {
-                LambdaPropertyDescriptor lpd = new LambdaPropertyDescriptor();
-                lpd.wrapped = pd;
- 
-                Method getter = pd.getReadMethod();
-                if (getter != null)
-                {
-                    MethodHandle getterHandle = lookup.unreflect(getter);
-                    CallSite getterCallSite = LambdaMetafactory.metafactory(lookup,
-                            "apply",
-                            MethodType.methodType(Function.class),
-                            MethodType.methodType(Object.class, Object.class),
-                            getterHandle,
-                            getterHandle.type());
-                    lpd.readFunction = (Function) getterCallSite.getTarget().invokeExact();
-                }
-
-                Method setter = pd.getWriteMethod();
-                if (setter != null)
-                {
-                    MethodHandle setterHandle = lookup.unreflect(setter);
-                    lpd.writeFunction = createSetter(lookup, lpd, setterHandle);
-                }
-                
+                LambdaPropertyDescriptor lpd = createLambdaPropertyDescriptor(pd, lookup);
                 properties.put(pd.getName(), lpd);
             }
             
@@ -127,7 +162,7 @@ public class MethodHandleUtils
         }
         catch (Throwable e)
         {
-            throw new ELException(e);
+            throw new FacesException(e);
         }
     }