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 2020/01/16 12:01:14 UTC
[isis] branch master updated: ISIS-2158: refactoring all reflective
constructor usages
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 3e5b4c8 ISIS-2158: refactoring all reflective constructor usages
3e5b4c8 is described below
commit 3e5b4c83d4b29da61de083b5bf5ecced47e4cb89
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Jan 16 13:01:00 2020 +0100
ISIS-2158: refactoring all reflective constructor usages
---
.../core/commons/internal/reflection/_Reflect.java | 62 +++---
.../core/metamodel/facets/DomainEventHelper.java | 222 +++++++++------------
.../metamodel/facets/jaxb/JaxbFacetFactory.java | 52 +++--
.../mixin/MetaModelValidatorForMixinTypes.java | 34 +++-
.../mixin/MixinFacetForDomainObjectAnnotation.java | 10 +-
.../object/mixin/MixinFacetForMixinAnnotation.java | 9 +-
.../objectmanager/create/ObjectCreator.java | 2 +-
.../create/ObjectCreator_builtinHandlers.java | 5 -
.../identify/ObjectIdentifier_builtinHandlers.java | 6 +-
.../factory/FactoryServiceDefault.java | 62 +++---
10 files changed, 232 insertions(+), 232 deletions(-)
diff --git a/core/commons/src/main/java/org/apache/isis/core/commons/internal/reflection/_Reflect.java b/core/commons/src/main/java/org/apache/isis/core/commons/internal/reflection/_Reflect.java
index f37e801..b29c378 100644
--- a/core/commons/src/main/java/org/apache/isis/core/commons/internal/reflection/_Reflect.java
+++ b/core/commons/src/main/java/org/apache/isis/core/commons/internal/reflection/_Reflect.java
@@ -27,11 +27,11 @@ import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.Optional;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
@@ -43,14 +43,15 @@ import javax.annotation.Nullable;
import org.springframework.core.annotation.AnnotationUtils;
-import org.apache.isis.core.commons.internal.base._Strings;
-import org.apache.isis.core.commons.internal.collections._Arrays;
+import org.apache.isis.core.commons.collections.Can;
import org.apache.isis.core.commons.internal.base._NullSafe;
+import org.apache.isis.core.commons.internal.base._Strings;
import org.apache.isis.core.commons.internal.base._With;
-
-import static org.apache.isis.core.commons.internal.base._NullSafe.stream;
+import org.apache.isis.core.commons.internal.collections._Arrays;
+import org.apache.isis.core.commons.internal.functions._Predicates;
import lombok.val;
+import lombok.experimental.UtilityClass;
/**
* <h1>- internal use only -</h1>
@@ -407,29 +408,42 @@ public final class _Reflect {
return null;
}
+
// -- COMMON CONSTRUCTOR IDIOMS
-
- public static boolean hasPublic1ArgConstructor(Class<?> cls) {
- val constructors = cls.getConstructors();
- for (val constructor : constructors) {
- if(constructor.getParameterCount()==1 &&
- Modifier.isPublic(constructor.getModifiers())) {
- return true;
- }
- }
- return false;
+
+ public static Can<Constructor<?>> getDeclaredConstructors(Class<?> cls) {
+ return Can.ofArray(cls.getDeclaredConstructors());
}
-
- public static Optional<Constructor<?>> getPublic1ArgConstructor(Class<?> cls) {
- val constructors = cls.getConstructors();
- for (val constructor : constructors) {
- if(constructor.getParameterCount()==1 &&
- Modifier.isPublic(constructor.getModifiers())) {
- return Optional.of(constructor);
+
+ public static Can<Constructor<?>> getPublicConstructors(Class<?> cls) {
+ return Can.ofArray(cls.getConstructors());
+ }
+
+ // -- FILTER
+
+ @UtilityClass
+ public static class Filter {
+
+ public static Predicate<Executable> isPublic() {
+ return ex->Modifier.isPublic(ex.getModifiers());
+ }
+
+ public static Predicate<Executable> paramCount(int paramCount) {
+ return ex->ex.getParameterCount() == paramCount;
+ }
+
+ public static Predicate<Executable> paramAssignableFrom(int paramIndex, Class<?> paramType) {
+ return ex->ex.getParameterTypes()[paramIndex].isAssignableFrom(paramType);
+ }
+
+ public static Predicate<Executable> paramAssignableFromValue(int paramIndex, @Nullable Object value) {
+ if(value==null) {
+ return _Predicates.alwaysTrue();
}
+ return ex->ex.getParameterTypes()[paramIndex].isAssignableFrom(value.getClass());
}
- return Optional.empty();
+
}
-
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
index 6c6f1b4..21bcd3e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
@@ -19,7 +19,6 @@
package org.apache.isis.core.metamodel.facets;
-import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
@@ -34,6 +33,7 @@ import org.apache.isis.applib.events.domain.PropertyDomainEvent;
import org.apache.isis.applib.services.registry.ServiceRegistry;
import org.apache.isis.core.commons.internal.assertions._Assert;
import org.apache.isis.core.commons.internal.collections._Lists;
+import org.apache.isis.core.commons.internal.reflection._Reflect;
import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
import org.apache.isis.core.metamodel.services.events.MetamodelEventService;
import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -42,6 +42,9 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramAssignableFrom;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramAssignableFromValue;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramCount;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@@ -161,40 +164,36 @@ public class DomainEventHelper {
final Object... arguments)
throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
+
+ val constructors = _Reflect.getPublicConstructors(type);
+
+ val noArgConstructors = constructors.filter(paramCount(0));
- final Constructor<?>[] constructors = type.getConstructors();
-
- // no-arg constructor
- for (final Constructor<?> constructor : type.getConstructors()) {
- if(constructor.getParameterCount() == 0) {
- final Object event = constructor.newInstance();
- final ActionDomainEvent<S> ade = uncheckedCast(event);
-
- ade.initSource(source);
- ade.setIdentifier(identifier);
- ade.setArguments(asList(arguments));
- return ade;
- }
+ for (val constructor : noArgConstructors) {
+
+ final Object event = constructor.newInstance();
+ final ActionDomainEvent<S> ade = uncheckedCast(event);
+
+ ade.initSource(source);
+ ade.setIdentifier(identifier);
+ ade.setArguments(asList(arguments));
+ return ade;
}
-
- for (final Constructor<?> constructor : constructors) {
- final Class<?>[] parameterTypes = constructor.getParameterTypes();
- if(parameterTypes.length != 3) {
- continue;
- }
- if(!parameterTypes[0].isAssignableFrom(source.getClass())) {
- continue;
- }
- if(!parameterTypes[1].isAssignableFrom(Identifier.class)) {
- continue;
- }
- if(!parameterTypes[2].isAssignableFrom(Object[].class)) {
- continue;
- }
- final Object event = constructor.newInstance(source, identifier, arguments);
+ // else
+
+ val updateEventConstructors = constructors
+ .filter(paramCount(3)
+ .and(paramAssignableFrom(0, source.getClass()))
+ .and(paramAssignableFrom(1, Identifier.class))
+ .and(paramAssignableFrom(2, Object[].class))
+ );
+
+ for (val constructor : updateEventConstructors) {
+ val event = constructor.newInstance(source, identifier, arguments);
return uncheckedCast(event);
}
+
throw new NoSuchMethodException(type.getName()+".<init>(? super " + source.getClass().getName() + ", " + Identifier.class.getName() + ", [Ljava.lang.Object;)");
}
@@ -261,43 +260,35 @@ public class DomainEventHelper {
final T oldValue,
final T newValue) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- final Constructor<?>[] constructors = type.getConstructors();
-
- // no-arg constructor
- for (final Constructor<?> constructor : constructors) {
- if(constructor.getParameterCount() == 0) {
- final Object event = constructor.newInstance();
- final PropertyDomainEvent<S, T> pde = uncheckedCast(event);
- pde.initSource(source);
- pde.setIdentifier(identifier);
- pde.setOldValue(oldValue);
- pde.setNewValue(newValue);
- return pde;
- }
+ val constructors = _Reflect.getPublicConstructors(type);
+
+ val noArgConstructors = constructors.filter(paramCount(0));
+
+ for (val constructor : noArgConstructors) {
+ final Object event = constructor.newInstance();
+ final PropertyDomainEvent<S, T> pde = uncheckedCast(event);
+ pde.initSource(source);
+ pde.setIdentifier(identifier);
+ pde.setOldValue(oldValue);
+ pde.setNewValue(newValue);
+ return pde;
}
// else
- for (final Constructor<?> constructor : constructors) {
- final Class<?>[] parameterTypes = constructor.getParameterTypes();
- if(parameterTypes.length != 4) {
- continue;
- }
- if(!parameterTypes[0].isAssignableFrom(source.getClass())) {
- continue;
- }
- if(!parameterTypes[1].isAssignableFrom(Identifier.class)) {
- continue;
- }
- if(oldValue != null && !parameterTypes[2].isAssignableFrom(oldValue.getClass())) {
- continue;
- }
- if(newValue != null && !parameterTypes[3].isAssignableFrom(newValue.getClass())) {
- continue;
- }
- final Object event = constructor.newInstance(source, identifier, oldValue, newValue);
+ val updateEventConstructors = constructors
+ .filter(paramCount(4)
+ .and(paramAssignableFrom(0, source.getClass()))
+ .and(paramAssignableFrom(1, Identifier.class))
+ .and(paramAssignableFromValue(2, oldValue))
+ .and(paramAssignableFromValue(3, newValue))
+ );
+
+ for (val constructor : updateEventConstructors) {
+ val event = constructor.newInstance(source, identifier, oldValue, newValue);
return uncheckedCast(event);
}
+ // else
throw new NoSuchMethodException(type.getName()+".<init>(? super " + source.getClass().getName() + ", " + Identifier.class.getName() + ", java.lang.Object, java.lang.Object)");
}
@@ -352,88 +343,57 @@ public class DomainEventHelper {
throws NoSuchMethodException, SecurityException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- final Constructor<?>[] constructors = type.getConstructors();
-
- // no-arg constructor
- for (final Constructor<?> constructor : constructors) {
- if(constructor.getParameterCount() == 0) {
- final Object event = constructor.newInstance();
- final CollectionDomainEvent<S, T> cde = uncheckedCast(event);
+ val constructors = _Reflect.getPublicConstructors(type);
- cde.initSource(source);
- cde.setIdentifier(identifier);
- cde.setOf(of);
- cde.setValue(value);
- return cde;
- }
+ val noArgConstructors = constructors.filter(paramCount(0));
+
+ for (val constructor : noArgConstructors) {
+ final Object event = constructor.newInstance();
+ final CollectionDomainEvent<S, T> cde = uncheckedCast(event);
+
+ cde.initSource(source);
+ cde.setIdentifier(identifier);
+ cde.setOf(of);
+ cde.setValue(value);
+ return cde;
}
-
+
+ // else
// search for constructor accepting source, identifier, type, value
- for (final Constructor<?> constructor : constructors) {
- final Class<?>[] parameterTypes = constructor.getParameterTypes();
- if(parameterTypes.length != 4) {
- continue;
- }
- if(!parameterTypes[0].isAssignableFrom(source.getClass())) {
- continue;
- }
- if(!parameterTypes[1].isAssignableFrom(Identifier.class)) {
- continue;
- }
- if(!parameterTypes[2].isAssignableFrom(CollectionDomainEvent.Of.class)) {
- continue;
- }
- if(value != null && !parameterTypes[3].isAssignableFrom(value.getClass())) {
- continue;
- }
- final Object event = constructor.newInstance(source, identifier, of, value);
+ val updateEventConstructors = constructors
+ .filter(paramCount(4)
+ .and(paramAssignableFrom(0, source.getClass()))
+ .and(paramAssignableFrom(1, Identifier.class))
+ .and(paramAssignableFrom(2, CollectionDomainEvent.Of.class))
+ .and(paramAssignableFromValue(3, value))
+ );
+
+ for (val constructor : updateEventConstructors) {
+ val event = constructor.newInstance(source, identifier, of, value);
return uncheckedCast(event);
}
+
+ // else
if(phase == AbstractDomainEvent.Phase.EXECUTED) {
- if(of == CollectionDomainEvent.Of.ADD_TO) {
- // support for @PostsCollectionAddedTo annotation:
+ if(of == CollectionDomainEvent.Of.ADD_TO
+ || of == CollectionDomainEvent.Of.REMOVE_FROM) {
+ // support for annotations @PostsCollectionAddedTo and @PostsCollectionRemovedFrom:
// search for constructor accepting source, identifier, value
- for (final Constructor<?> constructor : constructors) {
- final Class<?>[] parameterTypes = constructor.getParameterTypes();
- if(parameterTypes.length != 3) {
- continue;
- }
- if(!parameterTypes[0].isAssignableFrom(source.getClass())) {
- continue;
- }
- if(!parameterTypes[1].isAssignableFrom(Identifier.class)) {
- continue;
- }
- if(value != null && !parameterTypes[2].isAssignableFrom(value.getClass())) {
- continue;
- }
- final Object event = constructor.newInstance(source, identifier, value);
- return uncheckedCast(event);
- }
- } else if(of == CollectionDomainEvent.Of.REMOVE_FROM) {
- // support for @PostsCollectionRemovedFrom annotation:
- // search for constructor accepting source, identifier, value
- for (final Constructor<?> constructor : constructors) {
- final Class<?>[] parameterTypes = constructor.getParameterTypes();
- if(parameterTypes.length != 3) {
- continue;
- }
- if(!parameterTypes[0].isAssignableFrom(source.getClass())) {
- continue;
- }
- if(!parameterTypes[1].isAssignableFrom(Identifier.class)) {
- continue;
- }
- if(value != null && !parameterTypes[2].isAssignableFrom(value.getClass())) {
- continue;
- }
- final Object event = constructor.newInstance(
- source, identifier, value);
+ val eventConstructors = constructors
+ .filter(paramCount(3)
+ .and(paramAssignableFrom(0, source.getClass()))
+ .and(paramAssignableFrom(1, Identifier.class))
+ .and(paramAssignableFromValue(2, value))
+ );
+ for (val constructor : eventConstructors) {
+ val event = constructor.newInstance(source, identifier, of, value);
return uncheckedCast(event);
}
}
}
+
+ // else
throw new NoSuchMethodException(type.getName()+".<init>(? super " + source.getClass().getName() + ", " + Identifier.class.getName() + ", java.lang.Object)");
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java
index ba17599..bdbd35a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java
@@ -19,7 +19,6 @@
package org.apache.isis.core.metamodel.facets.jaxb;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -36,8 +35,8 @@ import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.isis.core.commons.internal.collections._Lists;
+import org.apache.isis.core.commons.internal.reflection._Reflect;
import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.core.metamodel.commons.MethodUtil;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
@@ -53,6 +52,11 @@ import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.isPublic;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramCount;
+
+import lombok.val;
+
/**
* just adds a validator
*/
@@ -385,25 +389,33 @@ implements MetaModelRefiner {
final ObjectSpecification objectSpec,
final MetaModelValidator validator) {
- final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
- final Constructor<?>[] constructors = correspondingClass.getDeclaredConstructors();
- for (Constructor<?> constructor : constructors) {
- if(constructor.getParameterCount() == 0) {
- if (!MethodUtil.isPublic(constructor)) {
- validator.onFailure(
- objectSpec,
- objectSpec.getIdentifier(),
- "JAXB view model '%s' has a no-arg constructor, however it is not public",
- objectSpec.getFullIdentifier());
- }
- return;
- }
+ val correspondingClass = objectSpec.getCorrespondingClass();
+
+ val publicNoArgConstructors = _Reflect
+ .getPublicConstructors(correspondingClass)
+ .filter(paramCount(0));
+
+ if(publicNoArgConstructors.getCardinality().isOne()) {
+ return; // happy case
+ }
+
+ val privateNoArgConstructors = _Reflect
+ .getDeclaredConstructors(correspondingClass)
+ .filter(paramCount(0).and(isPublic().negate()));
+
+ if(privateNoArgConstructors.isNotEmpty()) {
+ validator.onFailure(
+ objectSpec,
+ objectSpec.getIdentifier(),
+ "JAXB view model '%s' has a no-arg constructor, however it is not public",
+ objectSpec.getFullIdentifier());
+ } else {
+ validator.onFailure(
+ objectSpec,
+ objectSpec.getIdentifier(),
+ "JAXB view model '%s' does not have a public no-arg constructor",
+ objectSpec.getFullIdentifier());
}
- validator.onFailure(
- objectSpec,
- objectSpec.getIdentifier(),
- "JAXB view model '%s' does not have a public no-arg constructor",
- objectSpec.getFullIdentifier());
}
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
index 834115f..683dfb5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MetaModelValidatorForMixinTypes.java
@@ -23,7 +23,10 @@ import org.apache.isis.core.commons.internal.reflection._Reflect;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramCount;
+
import lombok.NonNull;
+import lombok.val;
public class MetaModelValidatorForMixinTypes extends MetaModelValidatorForValidationFailures {
@@ -37,17 +40,30 @@ public class MetaModelValidatorForMixinTypes extends MetaModelValidatorForValida
@NonNull FacetHolder facetHolder,
final Class<?> candidateMixinType) {
- if (_Reflect.hasPublic1ArgConstructor(candidateMixinType)) {
- return true;
- }
+ val mixinContructors = _Reflect
+ .getPublicConstructors(candidateMixinType)
+ .filter(paramCount(1));
- onFailure(
- facetHolder,
- Identifier.classIdentifier(candidateMixinType),
- "%s: annotated with %s annotation but does not have a public 1-arg constructor",
- candidateMixinType.getName(),
- annotation);
+ if(mixinContructors.getCardinality().isOne()) {
+ return true; // happy case
+ }
+ if(mixinContructors.getCardinality().isZero()) {
+ onFailure(
+ facetHolder,
+ Identifier.classIdentifier(candidateMixinType),
+ "%s: annotated with %s annotation but does not have a public 1-arg constructor",
+ candidateMixinType.getName(),
+ annotation);
+ } else {
+ onFailure(
+ facetHolder,
+ Identifier.classIdentifier(candidateMixinType),
+ "%s: annotated with %s annotation needs a single public 1-arg constructor but has %d",
+ candidateMixinType.getName(),
+ annotation,
+ mixinContructors.size());
+ }
return false;
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForDomainObjectAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForDomainObjectAnnotation.java
index fed0b78..ecc9c0a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForDomainObjectAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForDomainObjectAnnotation.java
@@ -29,7 +29,9 @@ import org.apache.isis.core.commons.internal.reflection._Reflect;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import lombok.val;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramCount;
+
+import lombok.val;
public class MixinFacetForDomainObjectAnnotation extends MixinFacetAbstract {
@@ -56,9 +58,11 @@ public class MixinFacetForDomainObjectAnnotation extends MixinFacetAbstract {
.filter(domainObject -> domainObject.nature() == Nature.MIXIN)
.map(domainObject -> {
- val constructorIfAny = _Reflect.getPublic1ArgConstructor(candidateMixinType);
+ val mixinContructors = _Reflect
+ .getPublicConstructors(candidateMixinType)
+ .filter(paramCount(1));
- return constructorIfAny
+ return mixinContructors.getSingleton() // empty if cardinality!=1
.map(constructor -> new MixinFacetForDomainObjectAnnotation(
candidateMixinType,
domainObject.mixinMethod(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForMixinAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForMixinAnnotation.java
index 8927cc3..f52fd77 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForMixinAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/mixin/MixinFacetForMixinAnnotation.java
@@ -27,6 +27,8 @@ import org.apache.isis.core.commons.internal.reflection._Reflect;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramCount;
+
import lombok.val;
public class MixinFacetForMixinAnnotation extends MixinFacetAbstract {
@@ -50,8 +52,11 @@ public class MixinFacetForMixinAnnotation extends MixinFacetAbstract {
final FacetHolder facetHolder,
final ServiceInjector servicesInjector) {
- val constructorIfAny = _Reflect.getPublic1ArgConstructor(candidateMixinType);
- return constructorIfAny
+ val mixinContructors = _Reflect
+ .getPublicConstructors(candidateMixinType)
+ .filter(paramCount(1));
+
+ return mixinContructors.getSingleton() // empty if cardinality!=1
.map(constructor -> new MixinFacetForMixinAnnotation(
candidateMixinType,
mixin.method(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator.java
index 7ddd48d..52adc96 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator.java
@@ -75,7 +75,7 @@ public interface ObjectCreator {
return request -> chainOfRespo
.handle(request)
.orElseThrow(()->_Exceptions.unrecoverableFormatted(
- "ObjectLoader failed to hanlde request %s", request));
+ "ObjectCreator failed to hanlde request %s", request));
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator_builtinHandlers.java
index 03e1c628..a2bb3ec 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/create/ObjectCreator_builtinHandlers.java
@@ -60,8 +60,6 @@ final class ObjectCreator_builtinHandlers {
@Override
public ManagedObject handle(ObjectCreator.Request objectCreateRequest) {
- //XXX legacy of objectAdapterContext.objectCreationMixin.newInstance(objectSpec);
-
val spec = objectCreateRequest.getObjectSpecification();
if (log.isDebugEnabled()) {
@@ -107,9 +105,6 @@ final class ObjectCreator_builtinHandlers {
.forEach(field->field.toDefault(adapter));
val pojo = adapter.getPojo();
-
- //XXX pojo already got everything injected above
- //metaModelContext.getServiceInjector().injectServicesInto(pojo);
CallbackFacet.Util.callCallback(adapter, CreatedCallbackFacet.class);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java
index 28781e7..7df40f0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectIdentifier_builtinHandlers.java
@@ -61,7 +61,7 @@ class ObjectIdentifier_builtinHandlers {
@Override
public RootOid handle(ManagedObject managedObject) {
final String identifier = SERVICE_IDENTIFIER;
- return Oid.Factory.persistentOf(managedObject.getSpecification().getSpecId(), identifier);
+ return Oid.Factory.of(managedObject.getSpecification().getSpecId(), identifier);
}
}
@@ -83,7 +83,7 @@ class ObjectIdentifier_builtinHandlers {
throw _Exceptions.unrecoverable(msg);
}
val identifier = entityFacet.identifierFor(spec, pojo);
- return Oid.Factory.persistentOf(spec.getSpecId(), identifier);
+ return Oid.Factory.of(spec.getSpecId(), identifier);
}
}
@@ -130,7 +130,7 @@ class ObjectIdentifier_builtinHandlers {
public RootOid handle(ManagedObject managedObject) {
val spec = managedObject.getSpecification();
val identifier = UUID.randomUUID().toString();
- return Oid.Factory.transientOf(spec.getSpecId(), identifier);
+ return Oid.Factory.of(spec.getSpecId(), identifier);
}
}
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 c5a1506..3094598 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
@@ -19,7 +19,6 @@
package org.apache.isis.core.runtimeservices.factory;
-import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.inject.Inject;
@@ -30,20 +29,21 @@ import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
-import org.apache.isis.applib.NonRecoverableException;
-import org.apache.isis.applib.ViewModel;
import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.core.commons.internal.base._Casts;
+import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.commons.internal.reflection._Reflect;
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.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.runtime.session.IsisSessionFactory;
import static org.apache.isis.core.commons.internal.base._With.requires;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramAssignableFrom;
+import static org.apache.isis.core.commons.internal.reflection._Reflect.Filter.paramCount;
import lombok.val;
@@ -60,37 +60,38 @@ public class FactoryServiceDefault implements FactoryService {
@Override
public <T> T instantiate(final Class<T> domainClass) {
- final ObjectSpecification spec = specificationLoader.loadSpecification(domainClass);
- final ManagedObject adapter = ManagedObject._newTransientInstance(spec);
+ val spec = specificationLoader.loadSpecification(domainClass);
+ val adapter = ManagedObject._newTransientInstance(spec);
return _Casts.uncheckedCast(adapter.getPojo());
}
@Override
public <T> T mixin(final Class<T> mixinClass, final Object mixedIn) {
- final ObjectSpecification objectSpec = specificationLoader.loadSpecification(mixinClass);
- final MixinFacet mixinFacet = objectSpec.getFacet(MixinFacet.class);
+ val objectSpec = specificationLoader.loadSpecification(mixinClass);
+ val mixinFacet = objectSpec.getFacet(MixinFacet.class);
if(mixinFacet == null) {
- throw new NonRecoverableException("Class '" + mixinClass.getName() + " is not a mixin");
+ throw _Exceptions.illegalArgument("Class '%s' is not a mixin", mixinClass.getName());
}
if(!mixinFacet.isMixinFor(mixedIn.getClass())) {
- throw new NonRecoverableException("Mixin class '" + mixinClass.getName() + " is not a mixin for supplied object '" + mixedIn + "'");
+ throw _Exceptions.illegalArgument("Mixin class '%s' is not a mixin for supplied object '%s'",
+ mixinClass.getName(), mixedIn);
}
- final Constructor<?>[] constructors = mixinClass.getConstructors();
- for (Constructor<?> constructor : constructors) {
- if(constructor.getParameterTypes().length == 1 &&
- constructor.getParameterTypes()[0].isAssignableFrom(mixedIn.getClass())) {
- final Object mixin;
- try {
- mixin = constructor.newInstance(mixedIn);
- return _Casts.uncheckedCast(serviceInjector.injectServicesInto(mixin));
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
- throw new NonRecoverableException(e);
- }
- }
+ 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));
+
+ try {
+ val mixin = mixinConstructor.newInstance(mixedIn);
+ return _Casts.uncheckedCast(serviceInjector.injectServicesInto(mixin));
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ throw _Exceptions.illegalArgument(
+ "Failed to invoke constructor of '%s' using single argument '%s'",
+ mixinClass.getName(), mixedIn);
}
- // should never get here because of previous guards
- throw new NonRecoverableException( String.format(
- "Failed to locate constructor in %s to instantiate using %s", mixinClass.getName(), mixedIn));
}
@Override
@@ -99,16 +100,9 @@ public class FactoryServiceDefault implements FactoryService {
val spec = specificationLoader.loadSpecification(viewModelClass);
if (!spec.containsFacet(ViewModelFacet.class)) {
- val msg = String.format("Type '%s' must be recogniced as a ViewModel, that is the type's meta-model "
+ throw _Exceptions.illegalArgument("Type '%s' must be recogniced as a ViewModel, "
+ + "that is the type's meta-model "
+ "must have an associated ViewModelFacet: ", viewModelClass.getName());
- throw new IllegalArgumentException(msg);
- }
-
- if(ViewModel.class.isAssignableFrom(viewModelClass)) {
- //FIXME[2152] is this execution branch required, or does the below code suffice for all cases?
- val viewModel = (ViewModel) instantiate(viewModelClass);
- viewModel.viewModelInit(mementoStr);
- return _Casts.uncheckedCast(viewModel);
}
val viewModelFacet = spec.getFacet(ViewModelFacet.class);