You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2020/01/05 17:54:54 UTC
[isis] 02/04: ISIS-2255: when reverse lookup of mixin,
also consider properties and collections.
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit d9b47234e3a8861f5349182104488e26a8280476
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Jan 5 17:20:26 2020 +0000
ISIS-2255: when reverse lookup of mixin, also consider properties and collections.
---
.../specloader/specimpl/MixedInMember.java | 2 +
.../specimpl/OneToManyAssociationMixedIn.java | 8 ++-
.../specimpl/OneToOneAssociationMixedIn.java | 6 +++
.../handlers/DomainObjectInvocationHandler.java | 58 ++++++++++++++--------
4 files changed, 51 insertions(+), 23 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/MixedInMember.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/MixedInMember.java
index 46a5d65..cc101af 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/MixedInMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/MixedInMember.java
@@ -20,6 +20,7 @@ package org.apache.isis.metamodel.specloader.specimpl;
import org.apache.isis.applib.annotation.Mixin;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.spec.feature.ObjectAction;
import org.apache.isis.metamodel.spec.feature.ObjectMember;
/**
@@ -34,5 +35,6 @@ public interface MixedInMember extends ObjectMember {
ObjectSpecification getMixinType();
+ boolean hasMixinAction(ObjectAction objectAction);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index 91dcaad..afa9e49 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -42,6 +42,7 @@ import org.apache.isis.metamodel.interactions.VisibilityContext;
import org.apache.isis.metamodel.services.publishing.PublisherDispatchService;
import org.apache.isis.metamodel.spec.ManagedObject;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.spec.feature.ObjectAction;
import lombok.Getter;
import lombok.val;
@@ -82,7 +83,7 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
// created from mixin actions.
val type = actionTypeOfFacet != null
? actionTypeOfFacet.value()
- : Object.class;
+ : (Class)Object.class;
return objectAction.getSpecificationLoader().loadSpecification(type);
}
@@ -211,6 +212,11 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
return getSpecificationLoader().loadSpecification(mixinType);
}
+ @Override
+ public boolean hasMixinAction(final ObjectAction mixinAction) {
+ return this.mixinAction == mixinAction;
+ }
+
private PublisherDispatchService getPublishingServiceInternal() {
return getServiceRegistry().lookupServiceElseFail(PublisherDispatchService.class);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index 97028f1..42e8ee0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -40,6 +40,7 @@ import org.apache.isis.metamodel.interactions.VisibilityContext;
import org.apache.isis.metamodel.services.publishing.PublisherDispatchService;
import org.apache.isis.metamodel.spec.ManagedObject;
import org.apache.isis.metamodel.spec.ObjectSpecification;
+import org.apache.isis.metamodel.spec.feature.ObjectAction;
import lombok.Getter;
import lombok.val;
@@ -197,6 +198,11 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
return getSpecificationLoader().loadSpecification(mixinType);
}
+ @Override
+ public boolean hasMixinAction(final ObjectAction mixinAction) {
+ return this.mixinAction == mixinAction;
+ }
+
private PublisherDispatchService getPublishingServiceInternal() {
return getServiceRegistry().lookupServiceElseFail(PublisherDispatchService.class);
}
diff --git a/core/runtime-services/src/main/java/org/apache/isis/runtime/services/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtime-services/src/main/java/org/apache/isis/runtime/services/wrapper/handlers/DomainObjectInvocationHandler.java
index fa7286b..ad992b5 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/runtime/services/wrapper/handlers/DomainObjectInvocationHandler.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/runtime/services/wrapper/handlers/DomainObjectInvocationHandler.java
@@ -29,7 +29,6 @@ import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.wrapper.DisabledException;
import org.apache.isis.applib.services.wrapper.HiddenException;
import org.apache.isis.applib.services.wrapper.InteractionException;
@@ -45,6 +44,7 @@ import org.apache.isis.applib.services.wrapper.events.VisibilityEvent;
import org.apache.isis.commons.collections.Can;
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.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.metamodel.consent.InteractionResult;
import org.apache.isis.metamodel.context.MetaModelContext;
@@ -63,6 +63,7 @@ import org.apache.isis.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.metamodel.specloader.SpecificationLoader;
import org.apache.isis.metamodel.specloader.specimpl.ContributeeMember;
+import org.apache.isis.metamodel.specloader.specimpl.MixedInMember;
import org.apache.isis.metamodel.specloader.specimpl.ObjectActionContributee;
import org.apache.isis.metamodel.specloader.specimpl.ObjectActionMixedIn;
import org.apache.isis.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
@@ -152,7 +153,8 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
}
- final ObjectSpecification targetNoSpec = targetAdapter.getSpecification();
+ final ObjectSpecification targetSpec = targetAdapter.getSpecification();
+ final ObjectSpecification targetNoSpec = targetSpec;
// save method, through the proxy
if (isSaveMethod(method)) {
@@ -223,34 +225,44 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
val objectAction = (ObjectAction) objectMember;
- ObjectAction actualObjectAction;
- ManagedObject actualTargetAdapter;
- val mixinFacet = targetAdapter.getSpecification().getFacet(MixinFacet.class);
+ val mixinFacet = targetSpec.getFacet(MixinFacet.class);
if(mixinFacet != null) {
// rather than invoke on a (transient) mixin, instead try to
- // figure out the corresponding ObjectActionMixedIn
- actualTargetAdapter = mixinFacet.mixedIn(targetAdapter, MixinFacet.Policy.IGNORE_FAILURES);
- actualObjectAction = determineMixinAction(actualTargetAdapter, objectAction);
-
- if(actualTargetAdapter == null || actualObjectAction == null) {
- // revert to original behaviour
- actualTargetAdapter = targetAdapter;
- actualObjectAction = objectAction;
+ // figure out the corresponding contributed member on the contributee.
+ final ManagedObject contributeeAdapter =
+ mixinFacet.mixedIn(targetAdapter, MixinFacet.Policy.IGNORE_FAILURES);
+
+ if (contributeeAdapter == null) {
+ throw _Exceptions.illegalState(String.format("Could not locate contributeeAdapter for action '%s'", objectAction.getId()));
+ }
+ final ObjectMember mixinMember = determineMixinMember(contributeeAdapter, objectAction);
+
+ if (mixinMember != null) {
+ if(mixinMember instanceof ObjectAction) {
+ return handleActionMethod(contributeeAdapter, args, (ObjectAction)mixinMember, contributeeMember);
+ }
+ if(mixinMember instanceof OneToOneAssociation) {
+ return handleGetterMethodOnProperty(contributeeAdapter, new Object[0], (OneToOneAssociation)mixinMember);
+ }
+ if(mixinMember instanceof OneToManyAssociation) {
+ return handleGetterMethodOnCollection(contributeeAdapter, new Object[0], (OneToManyAssociation)mixinMember, method, memberName);
+ }
+ } else {
+ throw _Exceptions.illegalState(String.format(
+ "Could not locate mixin member for action '%s' on spec '%s'", objectAction.getId(), targetSpec));
}
- } else {
- actualTargetAdapter = targetAdapter;
- actualObjectAction = objectAction;
}
- return handleActionMethod(actualTargetAdapter, args, actualObjectAction, contributeeMember);
+ // this is just a regular non-mixin action.
+ return handleActionMethod(targetAdapter, args, objectAction, contributeeMember);
}
throw new UnsupportedOperationException(String.format("Unknown member type '%s'", objectMember));
}
- private static ObjectAction determineMixinAction(
+ private static ObjectMember determineMixinMember(
final ManagedObject domainObjectAdapter,
final ObjectAction objectAction) {
@@ -259,11 +271,13 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
}
val specification = domainObjectAdapter.getSpecification();
val objectActions = specification.streamObjectActions(Contributed.INCLUDED);
+ val objectAssociations = specification.streamAssociations(Contributed.INCLUDED);
- return objectActions
- .filter(action->action instanceof ObjectActionMixedIn)
- .map(action->(ObjectActionMixedIn) action)
- .filter(mixedInAction->mixedInAction.hasMixinAction(objectAction))
+ final Stream<ObjectMember> objectMembers = Stream.concat(objectActions, objectAssociations);
+ return objectMembers
+ .filter(MixedInMember.class::isInstance)
+ .map(MixedInMember.class::cast)
+ .filter(mixedInMember->mixedInMember.hasMixinAction(objectAction))
.findFirst()
.orElse(null);