You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/01/25 18:22:36 UTC

[isis] branch master updated: ISIS-2497: optimization: eagerly find the holder field on mixin facet construction

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2cfc878  ISIS-2497: optimization: eagerly find the holder field on mixin facet construction
2cfc878 is described below

commit 2cfc878771aeac978cc0446a201ad902512b5202
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Jan 25 19:22:18 2021 +0100

    ISIS-2497: optimization: eagerly find the holder field on mixin facet
    construction
---
 .../facets/object/mixin/MixinFacetAbstract.java    | 33 ++++++++++++++--------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetAbstract.java
index 616d3f6..928a37f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetAbstract.java
@@ -20,9 +20,11 @@
 package org.apache.isis.core.metamodel.facets.object.mixin;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
+import java.util.Optional;
 
 import org.apache.isis.commons.functional.Result;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -43,6 +45,7 @@ implements MixinFacet {
     private final Class<?> mixinType;
     private final Class<?> holderType;
     private final Constructor<?> constructor;
+    private final Field holderField; // XXX validators should check whether we found the field
 
     public static Class<? extends Facet> type() {
         return MixinFacet.class;
@@ -59,6 +62,18 @@ implements MixinFacet {
         this.constructor = constructor;
         // by mixin convention: first constructor argument is identified as the holder type
         this.holderType = constructor.getParameterTypes()[0]; 
+        // search the type hierarchy of the mixin type for any matching (public and non-public) fields
+        this.holderField = _Reflect.streamAllFields(mixinType, true)
+                .filter(mixinField->mixinField.getType().isAssignableFrom(holderType))
+                .findFirst()
+                .orElse(null);
+        
+        if(holderField==null) {
+            log.warn("Could not find or access the 'mixed-in' domain object within {}" 
+                            + " (tried to guess by looking at all public and non-public fields "
+                            + "and matching one against the constructor parameter's type)", 
+                            mixinType.getClass().getName());
+        }
     }
 
     @Override
@@ -135,21 +150,17 @@ implements MixinFacet {
 
     private Object holderPojoFor(Object mixinPojo, Policy policy) {
         
-        //XXX optimization: we could memoize the field (not its value), if found
-        
-        // search the type hierarchy of the mixin type for any matching (public and non-public) fields
-        val holderPojoSearchResult = _Reflect.streamAllFields(mixinType, true)
-        .filter(mixinField->mixinField.getType().isAssignableFrom(holderType))
-        .findFirst()
-        .map(mixinField->Result.of(()->_Reflect.getFieldOn(mixinField, mixinPojo)))
+        val holderPojoGetterResult = Optional.ofNullable(holderField)
+        .map(field->Result.of(()->_Reflect.getFieldOn(field, mixinPojo)))
         .orElseGet(()->Result.failure("no such field"));
                 
-        if(holderPojoSearchResult.isFailure()) {
+        if(holderPojoGetterResult.isFailure()) {
             
             val msg = String.format(
-                    "Could not find or access the \"mixed-in\" domain object within %s" 
+                    "Could not %s the \"mixed-in\" domain object within %s" 
                             + " (tried to guess by looking at all public and non-public fields "
-                            + "and matching one against the constructor parameter's type)", 
+                            + "and matching one against the constructor parameter's type)",
+                            holderField==null ? "find" : "access",
                             getTitleService().titleOf(mixinPojo));
             
             log.warn(msg);
@@ -159,6 +170,6 @@ implements MixinFacet {
             }
         }
 
-        return holderPojoSearchResult.nullableOrElse(null);
+        return holderPojoGetterResult.nullableOrElse(null);
     }
 }