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 2022/01/29 10:20:56 UTC
[isis] branch master updated: ISIS-2950: [Async Wrapper] fixes mixin proxy creation
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 fffc31f ISIS-2950: [Async Wrapper] fixes mixin proxy creation
fffc31f is described below
commit fffc31fade4356f84cf121e9c05e1b234e6f3fff
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jan 29 11:20:48 2022 +0100
ISIS-2950: [Async Wrapper] fixes mixin proxy creation
- when the minxin's single arg constructor type not exactly matches the
mixee instance's type; in other words, when inherited
---
.../progmodel/ProgrammingModelConstants.java | 31 ++++++++++++++++++++++
.../factory/FactoryServiceDefault.java | 14 +++-------
.../wrapper/WrapperFactoryDefault.java | 6 ++++-
3 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java b/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java
index d2bb56b..dafaf24 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/progmodel/ProgrammingModelConstants.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.config.progmodel;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -42,8 +43,14 @@ import org.apache.isis.applib.annotation.ObjectLifecycle;
import org.apache.isis.applib.annotation.ObjectSupport;
import org.apache.isis.applib.services.i18n.TranslatableString;
import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.base._Refs;
import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.commons.internal.reflection._Reflect;
+
+import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramAssignableFrom;
+import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramCount;
import lombok.Getter;
import lombok.NonNull;
@@ -115,6 +122,30 @@ public final class ProgrammingModelConstants {
}
}
+ // -- MIXIN CONSTRUCTION
+
+ public enum MixinConstructor {
+ /**
+ * Assuming, mixins do have a public single argument constructor,
+ * that receive an instance of the mixee's type.
+ */
+ PUBLIC_SINGLE_ARG_RECEIVING_MIXEE;
+
+ // while this enum only has a single value, we just provide a (quasi) static method here
+ public <T> Constructor<T> lookupConstructor(
+ final @NonNull Class<T> mixinClass,
+ final @NonNull Class<?> mixeeClass) {
+ return _Casts.uncheckedCast(_Reflect
+ .getPublicConstructors(mixinClass)
+ .filter(paramCount(1).and(paramAssignableFrom(0, mixeeClass)))
+ .getSingleton()
+ .orElseThrow(()->_Exceptions.illegalArgument(
+ "Failed to locate constructor in '%s' to instantiate,"
+ + "when using type '%s' as first argument",
+ mixinClass.getName(), mixinClass.getName())));
+ }
+ }
+
// -- LIFECYCLE CALLBACKS
@Getter
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
index 4b835a8..cddb527 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
@@ -35,8 +35,8 @@ import org.apache.isis.applib.services.iactnlayer.InteractionService;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.commons.internal.reflection._Reflect;
import org.apache.isis.core.config.environment.IsisSystemEnvironment;
+import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MixinConstructor;
import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacet;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.services.objectlifecycle.ObjectLifecyclePublisher;
@@ -44,9 +44,6 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramAssignableFrom;
-import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramCount;
-
import lombok.NonNull;
import lombok.val;
@@ -114,13 +111,8 @@ public class FactoryServiceDefault implements FactoryService {
throw _Exceptions.illegalArgument("Mixin class '%s' is not a mixin for supplied object '%s'",
mixinClass.getName(), mixedIn);
}
- val mixinConstructor = _Reflect
- .getPublicConstructors(mixinClass)
- .filter(paramCount(1).and(paramAssignableFrom(0, mixedIn.getClass())))
- .getSingleton()
- .orElseThrow(()->_Exceptions.illegalArgument(
- "Failed to locate constructor in '%s' to instantiate using '%s'",
- mixinClass.getName(), mixedIn));
+ val mixinConstructor = MixinConstructor.PUBLIC_SINGLE_ARG_RECEIVING_MIXEE
+ .lookupConstructor(mixinClass, mixedIn.getClass());
try {
val mixin = mixinConstructor.newInstance(mixedIn);
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index 5a22951..cdd51f4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -86,6 +86,7 @@ import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Arrays;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.commons.internal.proxy._ProxyFactoryService;
+import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MixinConstructor;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.interactions.InteractionHead;
import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
@@ -310,8 +311,11 @@ public class WrapperFactoryDefault implements WrapperFactory {
val mixeeAdapter = adaptAndGuardAgainstWrappingNotSupported(mixee);
val mixinAdapter = adaptAndGuardAgainstWrappingNotSupported(mixin);
+ val mixinConstructor = MixinConstructor.PUBLIC_SINGLE_ARG_RECEIVING_MIXEE
+ .lookupConstructor(mixinClass, mixee.getClass());
+
val proxyFactory = proxyFactoryService
- .factory(mixinClass, new Class[]{WrappingObject.class}, new Class[]{mixee.getClass()});
+ .factory(mixinClass, new Class[]{WrappingObject.class}, mixinConstructor.getParameterTypes());
return proxyFactory.createInstance((proxy, method, args) -> {