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 d5eea5d ISIS-2340: fixing some regressions from prev. commit(s) d5eea5d is described below commit d5eea5d2f500f6349e18d6dc3e75e825b2f83145 Author: Andi Huber <ahu...@apache.org> AuthorDate: Sun May 10 18:31:57 2020 +0200 ISIS-2340: fixing some regressions from prev. commit(s) further simplifying --- .../core/metamodel/facets/DomainEventHelper.java | 57 ++++++++++---------- .../invocation/ActionDomainEventFacetAbstract.java | 6 +-- .../action/invocation/ActionInvocationFacet.java | 4 +- ...ctionInvocationFacetForDomainEventAbstract.java | 13 +++-- ...ectionAddToFacetForDomainEventFromAbstract.java | 12 +++-- .../modify/CollectionDomainEventFacetAbstract.java | 6 +-- ...nRemoveFromFacetForDomainEventFromAbstract.java | 12 +++-- .../facets/object/mixin/MixinFacetAbstract.java | 21 ++++---- .../parser/ParseableFacetUsingParser.java | 7 +-- .../modify/PropertyDomainEventFacetAbstract.java | 6 +-- ...tySetterOrClearFacetForDomainEventAbstract.java | 19 ++++--- .../metamodel/interactions/InteractionContext.java | 56 +++++++++++++++---- .../core/metamodel/spec/feature/ObjectAction.java | 11 ++-- .../metamodel/spec/interaction/ManagedAction.java | 4 +- .../specloader/specimpl/ObjectActionDefault.java | 32 ++++++----- .../specloader/specimpl/ObjectActionMixedIn.java | 63 ++++------------------ .../specloader/specimpl/ObjectMemberAbstract.java | 9 ++-- .../specimpl/OneToManyAssociationMixedIn.java | 5 +- .../specimpl/OneToOneAssociationMixedIn.java | 8 ++- .../command/CommandExecutorServiceDefault.java | 5 +- .../handlers/DomainObjectInvocationHandler.java | 8 +-- .../jdo/dom/user/ApplicationUserRepository.java | 4 +- .../viewer/vaadin/ui/pages/main/MainView.java | 4 +- .../viewer/wicket/model/models/ActionModel.java | 7 +-- 24 files changed, 190 insertions(+), 189 deletions(-) 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 9fe41ef..adba4d4 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,6 +19,11 @@ package org.apache.isis.core.metamodel.facets; +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 java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; @@ -38,17 +43,13 @@ import org.apache.isis.core.commons.internal.collections._Lists; import org.apache.isis.core.commons.internal.exceptions._Exceptions; import org.apache.isis.core.commons.internal.reflection._Reflect; import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.services.events.MetamodelEventService; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.ObjectSpecification; 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; import lombok.val; @@ -72,13 +73,13 @@ public class DomainEventHelper { @NonNull final Class<? extends ActionDomainEvent<?>> eventType, final ObjectAction objectAction, final IdentifiedHolder identified, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final Can<ManagedObject> argumentAdapters, final ManagedObject resultAdapter) { - return postEventForAction(phase, uncheckedCast(eventType), /*existingEvent*/null, objectAction, identified, - targetAdapter, mixedInAdapter, argumentAdapters, resultAdapter); + return postEventForAction(phase, uncheckedCast(eventType), /*existingEvent*/null, + objectAction, identified, + head, argumentAdapters, resultAdapter); } // variant using existing event and not eventType (is derived from event) @@ -87,14 +88,13 @@ public class DomainEventHelper { @NonNull final ActionDomainEvent<?> existingEvent, final ObjectAction objectAction, final IdentifiedHolder identified, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final Can<ManagedObject> argumentAdapters, final ManagedObject resultAdapter) { return postEventForAction(phase, uncheckedCast(existingEvent.getClass()), existingEvent, objectAction, identified, - targetAdapter, mixedInAdapter, argumentAdapters, resultAdapter); + head, argumentAdapters, resultAdapter); } private <S> ActionDomainEvent<S> postEventForAction( @@ -103,8 +103,7 @@ public class DomainEventHelper { final ActionDomainEvent<S> existingEvent, final ObjectAction objectAction, final IdentifiedHolder identified, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final Can<ManagedObject> argumentAdapters, final ManagedObject resultAdapter) { @@ -118,15 +117,15 @@ public class DomainEventHelper { event = existingEvent; } else { // all other phases, create a new event - final S source = uncheckedCast(ManagedObject.unwrapSingle(targetAdapter)); + final S source = uncheckedCast(ManagedObject.unwrapSingle(head.getTarget())); final Object[] arguments = ManagedObject.unwrapMultipleAsArray(argumentAdapters); final Identifier identifier = identified.getIdentifier(); event = newActionDomainEvent(eventType, identifier, source, arguments); // copy over if have - if(mixedInAdapter != null ) { - event.setMixedIn(mixedInAdapter.getPojo()); - } + head.getMixedIn() + .ifPresent(mixedInAdapter-> + event.setMixedIn(mixedInAdapter.getPojo())); if(objectAction != null) { // should always be the case... @@ -215,8 +214,7 @@ public class DomainEventHelper { final Class<? extends PropertyDomainEvent<S, T>> eventType, final PropertyDomainEvent<S, T> existingEvent, final IdentifiedHolder identified, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final T oldValue, final T newValue) { @@ -224,7 +222,7 @@ public class DomainEventHelper { try { final PropertyDomainEvent<S, T> event; - final S source = uncheckedCast(ManagedObject.unwrapSingle(targetAdapter)); + final S source = uncheckedCast(ManagedObject.unwrapSingle(head.getTarget())); final Identifier identifier = identified.getIdentifier(); if(existingEvent != null && phase.isExecuted()) { @@ -235,9 +233,9 @@ public class DomainEventHelper { event = newPropertyDomainEvent(eventType, identifier, source, oldValue, newValue); // copy over if have - if(mixedInAdapter != null ) { - event.setMixedIn(mixedInAdapter.getPojo()); - } + head.getMixedIn() + .ifPresent(mixedInAdapter-> + event.setMixedIn(mixedInAdapter.getPojo())); } @@ -304,8 +302,7 @@ public class DomainEventHelper { final Class<? extends CollectionDomainEvent<S, T>> eventType, final CollectionDomainEvent<S, T> existingEvent, final IdentifiedHolder identified, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final CollectionDomainEvent.Of of, final T reference) { @@ -318,14 +315,14 @@ public class DomainEventHelper { event = existingEvent; } else { // all other phases, create a new event - final S source = uncheckedCast(ManagedObject.unwrapSingle(targetAdapter)); + final S source = uncheckedCast(ManagedObject.unwrapSingle(head.getTarget())); final Identifier identifier = identified.getIdentifier(); event = newCollectionDomainEvent(eventType, phase, identifier, source, of, reference); // copy over if have - if(mixedInAdapter != null ) { - event.setMixedIn(mixedInAdapter.getPojo()); - } + head.getMixedIn() + .ifPresent(mixedInAdapter-> + event.setMixedIn(mixedInAdapter.getPojo())); } event.setEventPhase(phase); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java index 65d6846..3f31059 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java @@ -77,7 +77,7 @@ implements ActionDomainEventFacet { AbstractDomainEvent.Phase.HIDE, getEventType(), actionFrom(ic), getIdentified(), - ic.getTarget(), ic.getMixedIn(), argumentAdaptersFrom(ic), + ic.getHead(), argumentAdaptersFrom(ic), null); if (event != null && event.isHidden()) { return "Hidden by subscriber"; @@ -93,7 +93,7 @@ implements ActionDomainEventFacet { AbstractDomainEvent.Phase.DISABLE, getEventType(), actionFrom(ic), getIdentified(), - ic.getTarget(), ic.getMixedIn(), argumentAdaptersFrom(ic), + ic.getHead(), argumentAdaptersFrom(ic), null); if (event != null && event.isDisabled()) { final TranslatableString reasonTranslatable = event.getDisabledReasonTranslatable(); @@ -118,7 +118,7 @@ implements ActionDomainEventFacet { AbstractDomainEvent.Phase.VALIDATE, getEventType(), actionFrom(ic), getIdentified(), - ic.getTarget(), ic.getMixedIn(), aic.getArgs(), + ic.getHead(), aic.getArgs(), null); if (event != null && event.isInvalid()) { final TranslatableString reasonTranslatable = event.getInvalidityReasonTranslatable(); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java index 8458c8e3..7653722 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java @@ -22,6 +22,7 @@ package org.apache.isis.core.metamodel.facets.actions.action.invocation; import org.apache.isis.core.commons.collections.Can; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.facetapi.Facet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.spec.feature.ObjectAction; @@ -38,8 +39,7 @@ public interface ActionInvocationFacet extends Facet { ManagedObject invoke( ObjectAction owningAction, - ManagedObject targetAdapter, - ManagedObject mixedInAdapter, // null for regular or contributed (not mixin) actions + Head head, Can<ManagedObject> argumentAdapters, InteractionInitiatedBy interactionInitiatedBy); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java index 3b44d6d..b2b8cc0 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java @@ -61,6 +61,7 @@ import org.apache.isis.core.metamodel.facets.ImperativeFacet; import org.apache.isis.core.metamodel.facets.actions.publish.PublishedActionFacet; import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFacet; import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal; import org.apache.isis.core.metamodel.services.publishing.PublisherDispatchService; import org.apache.isis.core.metamodel.spec.ManagedObject; @@ -116,11 +117,13 @@ implements ImperativeFacet { @Override public ManagedObject invoke( final ObjectAction owningAction, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final Can<ManagedObject> argumentAdapters, final InteractionInitiatedBy interactionInitiatedBy) { + val targetAdapter = head.getTarget(); + val mixedInAdapter = head.getMixedIn().orElse(null); + final ManagedObject executionResult = getTransactionService().executeWithinTransaction(()-> doInvoke(owningAction, targetAdapter, mixedInAdapter, argumentAdapters, @@ -433,6 +436,8 @@ implements ImperativeFacet { .asActionInvocationDto(owningAction, mixinElseRegularAdapter, argumentAdapters.toList()); currentExecution.setDto(invocationDto); + + val head = Head.mixedIn(targetAdapter, mixedInAdapter); // set the startedAt (and update command if this is the top-most member execution) @@ -449,7 +454,7 @@ implements ImperativeFacet { AbstractDomainEvent.Phase.EXECUTING, getEventType(), owningAction, owningAction, - targetAdapter, mixedInAdapter, argumentAdapters, + head, argumentAdapters, null); // set event onto the execution @@ -465,7 +470,7 @@ implements ImperativeFacet { domainEventHelper.postEventForAction( AbstractDomainEvent.Phase.EXECUTED, actionDomainEvent, - owningAction, owningAction, targetAdapter, mixedInAdapter, argumentAdapters, + owningAction, owningAction, head, argumentAdapters, resultAdapterPossiblyCloned); final Object returnValue = actionDomainEvent.getReturnValue(); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java index 31e8d4b..e013fce 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionAddToFacetForDomainEventFromAbstract.java @@ -32,6 +32,7 @@ import org.apache.isis.core.metamodel.facets.DomainEventHelper; import org.apache.isis.core.metamodel.facets.SingleValueFacetAbstract; import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet; import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.spec.ManagedObject; import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast; @@ -66,7 +67,8 @@ implements CollectionAddToFacet { @Override public void add( final ManagedObject targetAdapter, - final ManagedObject referencedObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy) { + final ManagedObject referencedObjectAdapter, + final InteractionInitiatedBy interactionInitiatedBy) { if (this.collectionAddToFacet == null) { return; } @@ -84,10 +86,10 @@ implements CollectionAddToFacet { } } - + final Head head = Head.simple(targetAdapter); + // either doesn't contain object, or doesn't have set semantics, so // execute the add wrapped between the executing and executed events ... - final ManagedObject mixedInAdapter = null; // ... post the executing event @@ -95,7 +97,7 @@ implements CollectionAddToFacet { domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTING, getEventType(), null, - getIdentified(), targetAdapter, mixedInAdapter, + getIdentified(), head, CollectionDomainEvent.Of.ADD_TO, referencedObject); @@ -106,7 +108,7 @@ implements CollectionAddToFacet { domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTED, getEventType(), uncheckedCast(event), - getIdentified(), targetAdapter, mixedInAdapter, + getIdentified(), head, CollectionDomainEvent.Of.ADD_TO, referencedObject); } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java index ff259b0..37bb38d 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionDomainEventFacetAbstract.java @@ -76,7 +76,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.HIDE, getEventType(), null, - getIdentified(), ic.getTarget(), ic.getMixedIn(), + getIdentified(), ic.getHead(), CollectionDomainEvent.Of.ACCESS, null); if (event != null && event.isHidden()) { @@ -92,7 +92,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.DISABLE, getEventType(), null, - getIdentified(), ic.getTarget(), ic.getMixedIn(), + getIdentified(), ic.getHead(), CollectionDomainEvent.Of.ACCESS, null); if (event != null && event.isDisabled()) { @@ -124,7 +124,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.VALIDATE, getEventType(), null, - getIdentified(), ic.getTarget(), ic.getMixedIn(), + getIdentified(), ic.getHead(), of, proposed); if (event != null && event.isInvalid()) { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java index edd1404..47c1741 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/modify/CollectionRemoveFromFacetForDomainEventFromAbstract.java @@ -19,6 +19,8 @@ package org.apache.isis.core.metamodel.facets.collections.collection.modify; +import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast; + import java.util.Collection; import java.util.Map; @@ -33,10 +35,9 @@ import org.apache.isis.core.metamodel.facets.DomainEventHelper; import org.apache.isis.core.metamodel.facets.SingleValueFacetAbstract; import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet; import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.spec.ManagedObject; -import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast; - public abstract class CollectionRemoveFromFacetForDomainEventFromAbstract extends SingleValueFacetAbstract<Class<? extends CollectionDomainEvent<?,?>>> @@ -86,16 +87,17 @@ implements CollectionRemoveFromFacet { return; } + final Head head = Head.simple(targetAdapter); + // contains the element, so // execute the remove wrapped between the executing and executed events ... - final ManagedObject mixedInAdapter = null; // ... post the executing event final CollectionDomainEvent<?, ?> event = domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTING, getEventType(), null, - getIdentified(), targetAdapter, mixedInAdapter, + getIdentified(), head, CollectionDomainEvent.Of.REMOVE_FROM, referencedObject); @@ -106,7 +108,7 @@ implements CollectionRemoveFromFacet { domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTED, getEventType(), uncheckedCast(event), - getIdentified(), targetAdapter, mixedInAdapter, + getIdentified(), head, CollectionDomainEvent.Of.REMOVE_FROM, referencedObject); } 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 081d62f..606b64a 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 @@ -24,6 +24,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; +import org.apache.isis.core.commons.internal.exceptions._Exceptions; 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; @@ -67,28 +68,24 @@ implements MixinFacet { @Override public Object instantiate(final Object domainPojo) { if(constructor == null) { - return null; // invalid mix-in declaration; ought we to fail-fast? + throw _Exceptions.unrecoverableFormatted( + "invalid mix-in declaration of type %s, missing contructor", mixinType); } if(domainPojo == null) { return null; } if(!isMixinFor(domainPojo.getClass())) { - // shouldn't happen; ought we to fail-fast instead? - return null; + throw _Exceptions.unrecoverableFormatted( + "invalid mix-in declaration of type %s, unexpect owner type %s", + mixinType, domainPojo.getClass()); } try { val mixinPojo = constructor.newInstance(domainPojo); getServiceInjector().injectServicesInto(mixinPojo); return mixinPojo; - } catch (InvocationTargetException e) { - // shouldn't happen; ought we to fail-fast instead? - return null; - } catch (InstantiationException e) { - // shouldn't happen; ought we to fail-fast instead? - return null; - } catch (IllegalAccessException e) { - // shouldn't happen; ought we to fail-fast instead? - return null; + } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { + throw _Exceptions.unrecoverableFormatted( + "invalid mix-in declaration of type %s, failing instance construction with %s", mixinType, e); } } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/parseable/parser/ParseableFacetUsingParser.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/parseable/parser/ParseableFacetUsingParser.java index 1516f30..c4a3598 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/parseable/parser/ParseableFacetUsingParser.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/parseable/parser/ParseableFacetUsingParser.java @@ -73,7 +73,9 @@ implements ParseableFacet { // check string is valid // (eg pick up any @RegEx on value type) - if (getFacetHolder().containsFacet(ValueFacet.class)) { + if (contextAdapter!=null + && getFacetHolder().containsFacet(ValueFacet.class)) { + val entryAdapter = getObjectManager().adapt(entry); final Identifier identifier = getIdentified().getIdentifier(); final ParseValueContext parseValueContext = @@ -99,8 +101,7 @@ implements ParseableFacet { final ObjectSpecification specification = adapter.getSpecification(); final ObjectValidityContext validateContext = specification.createValidityInteractionContext( - adapter, interactionInitiatedBy - ); + adapter, interactionInitiatedBy); validate(validateContext); return adapter; diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java index f3e47b1..665c9db 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetAbstract.java @@ -93,7 +93,7 @@ extends SingleClassValueFacetAbstract implements PropertyDomainEventFacet { domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.HIDE, getEventType(), null, - getIdentified(), ic.getTarget(), ic.getMixedIn(), + getIdentified(), ic.getHead(), null, null); if (event != null && event.isHidden()) { return "Hidden by subscriber"; @@ -108,7 +108,7 @@ extends SingleClassValueFacetAbstract implements PropertyDomainEventFacet { domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.DISABLE, getEventType(), null, - getIdentified(), ic.getTarget(), ic.getMixedIn(), + getIdentified(), ic.getHead(), null, null); if (event != null && event.isDisabled()) { final TranslatableString reasonTranslatable = event.getDisabledReasonTranslatable(); @@ -141,7 +141,7 @@ extends SingleClassValueFacetAbstract implements PropertyDomainEventFacet { domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.VALIDATE, getEventType(), null, - getIdentified(), ic.getTarget(), ic.getMixedIn(), + getIdentified(), ic.getHead(), oldValue, proposedValue); if (event != null && event.isInvalid()) { final TranslatableString reasonTranslatable = event.getInvalidityReasonTranslatable(); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java index 845ac93..cea72e1 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java @@ -19,6 +19,8 @@ package org.apache.isis.core.metamodel.facets.properties.property.modify; +import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast; + import java.util.Map; import java.util.Objects; @@ -42,14 +44,13 @@ import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollect import org.apache.isis.core.metamodel.facets.properties.publish.PublishedPropertyFacet; import org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyClearFacet; import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal; import org.apache.isis.core.metamodel.services.publishing.PublisherDispatchService; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation; import org.apache.isis.schema.ixn.v2.PropertyEditDto; -import static org.apache.isis.core.commons.internal.base._Casts.uncheckedCast; - import lombok.val; public abstract class PropertySetterOrClearFacetForDomainEventAbstract @@ -132,7 +133,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> { final InteractionInitiatedBy interactionInitiatedBy) { setOrClearProperty(Style.CLEAR, - owningProperty, targetAdapter, /*mixedInAdapter*/ null, interactionInitiatedBy); + owningProperty, targetAdapter, /*newValueAdapter*/ null, interactionInitiatedBy); } @@ -154,10 +155,8 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> { final ManagedObject newValueAdapter, final InteractionInitiatedBy interactionInitiatedBy) { - final ManagedObject mixedInAdapter = null; - getTransactionService().executeWithinTransaction(()->{ - doSetOrClearProperty(style, owningProperty, targetAdapter, mixedInAdapter, newValueAdapter, interactionInitiatedBy); + doSetOrClearProperty(style, owningProperty, Head.simple(targetAdapter), newValueAdapter, interactionInitiatedBy); }); } @@ -165,8 +164,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> { private void doSetOrClearProperty( final Style style, final OneToOneAssociation owningProperty, - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final ManagedObject newValueAdapter, final InteractionInitiatedBy interactionInitiatedBy) { @@ -202,6 +200,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> { } else { + val targetAdapter = head.getTarget(); final Object target = ManagedObject.unwrapSingle(targetAdapter); final Object argValue = ManagedObject.unwrapSingle(newValueAdapter); @@ -240,7 +239,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> { domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.EXECUTING, getEventType(), null, - getIdentified(), targetAdapter, mixedInAdapter, + getIdentified(), head, oldValue, newValue); // set event onto the execution @@ -260,7 +259,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> { domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.EXECUTED, getEventType(), uncheckedCast(event), - getIdentified(), targetAdapter, mixedInAdapter, + getIdentified(), head, oldValue, actualNewValue); } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java index 977ab0b..1255054 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionContext.java @@ -20,10 +20,14 @@ package org.apache.isis.core.metamodel.interactions; import java.util.Objects; +import java.util.Optional; + +import javax.annotation.Nullable; import org.apache.isis.applib.Identifier; import org.apache.isis.applib.annotation.Where; import org.apache.isis.applib.services.wrapper.events.InteractionEvent; +import org.apache.isis.core.commons.internal.exceptions._Exceptions; import org.apache.isis.core.metamodel.consent.InteractionContextType; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.facetapi.Facet; @@ -66,7 +70,7 @@ public abstract class InteractionContext { * Model that holds the objects involved with the interaction. * @since 2.0 */ - @Value(staticConstructor = "of") + @Value(staticConstructor = "of2") public static class Head { /** * The owning object that this interaction is associated with. @@ -78,10 +82,43 @@ public abstract class InteractionContext { */ @NonNull private final ManagedObject target; + /** in support of legacy code */ + public static Head of(@NonNull ManagedObject owner, @NonNull ManagedObject target) { + if(ManagedObject.isSpecified(owner) + && owner.getSpecification().getBeanSort().isMixin() + && owner.getPojo()==null) { + throw _Exceptions.unrecoverableFormatted("owner not spec. %s", owner); + } + if(ManagedObject.isSpecified(target) + && target.getSpecification().getBeanSort().isMixin() + && target.getPojo()==null) { + throw _Exceptions.unrecoverableFormatted("target not spec. %s", target); + } + return of2(owner, target); + } + /** when owner equals target (no mixin) */ public static Head simple(ManagedObject owner) { return Head.of(owner, owner); } + + /** + * as used by the domain event subsystem + * @return optionally the owner, if the target is a mixin + */ + public Optional<ManagedObject> getMixedIn() { + return Objects.equals(getOwner(), getTarget()) + ? Optional.empty() + : Optional.of(getOwner()); + } + + /** in support of legacy code */ + public static Head mixedIn(@NonNull ManagedObject target, @Nullable ManagedObject mixedIn) { + return mixedIn==null + ? of(target, target) + : of(mixedIn, target); + } + } /** @@ -121,17 +158,10 @@ public abstract class InteractionContext { @Getter private final Head head; /** - * The target object that this interaction is associated with. - */ - @Getter private final ManagedObject target; - - /** * Where the element is to be rendered. */ @Getter private final Where where; - @Getter private final ManagedObject mixedIn; // for mixin members only, obviously - protected InteractionContext( final InteractionContextType interactionType, final InteractionInitiatedBy invocationMethod, @@ -143,12 +173,16 @@ public abstract class InteractionContext { this.identifier = identifier; this.head = head; this.where = where; - - this.target = head.getTarget(); - this.mixedIn = Objects.equals(head.getOwner(), head.getTarget()) ? null : head.getOwner(); } + /** + * The target object that this interaction is associated with. + */ + public ManagedObject getTarget() { + return head.getTarget(); + } + /** * Convenience method that indicates whether the * {@link #getInitiatedBy() interaction was invoked} by the framework. diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java index c7a70e1..6c79feb 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java @@ -17,6 +17,8 @@ package org.apache.isis.core.metamodel.spec.feature; +import static org.apache.isis.core.commons.internal.base._NullSafe.stream; + import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -50,6 +52,7 @@ import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaFacet; import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet; import org.apache.isis.core.metamodel.facets.object.promptStyle.PromptStyleFacet; import org.apache.isis.core.metamodel.facets.object.wizard.WizardFacet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderFacetComparator; import org.apache.isis.core.metamodel.spec.ActionType; import org.apache.isis.core.metamodel.spec.ManagedObject; @@ -57,8 +60,6 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.specloader.specimpl.MixedInMember; import org.apache.isis.core.metamodel.specloader.specimpl.PendingParameterModelHead; -import static org.apache.isis.core.commons.internal.base._NullSafe.stream; - import lombok.NonNull; import lombok.val; @@ -108,8 +109,7 @@ public interface ObjectAction extends ObjectMember { * @param mixedInAdapter - will be null for regular actions, and for mixin actions. When a mixin action invokes its underlying mixedIn action, then will be populated (so that the ActionDomainEvent can correctly provide the underlying mixin) */ ManagedObject executeWithRuleChecking( - ManagedObject target, - ManagedObject mixedInAdapter, + Head head, Can<ManagedObject> parameters, InteractionInitiatedBy interactionInitiatedBy, Where where) throws AuthorizationException; @@ -123,8 +123,7 @@ public interface ObjectAction extends ObjectMember { * (so that the ActionDomainEvent can correctly provide the underlying mixin) */ ManagedObject execute( - ManagedObject targetAdapter, - ManagedObject mixedInAdapter, + Head head, Can<ManagedObject> parameters, InteractionInitiatedBy interactionInitiatedBy); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java index 6389ee0..cfb0da0 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/interaction/ManagedAction.java @@ -23,6 +23,7 @@ import java.util.Optional; import org.apache.isis.core.commons.collections.Can; import org.apache.isis.core.commons.internal.base._Either; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.feature.ObjectAction; @@ -76,9 +77,8 @@ public final class ManagedAction extends ManagedMember { //TODO validate params, and handle invocation exceptions - final ManagedObject mixedInAdapter = null; // filled in automatically ? val actionResult = getAction() - .execute(getOwner(), mixedInAdapter , actionParameters, InteractionInitiatedBy.USER); + .execute(Head.simple(getOwner()) , actionParameters, InteractionInitiatedBy.USER); return _Either.left(actionResult); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java index fe7c9d1..c592bc5 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java @@ -388,12 +388,13 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA @Override public ManagedObject executeWithRuleChecking( - final ManagedObject target, - final ManagedObject mixedInAdapter, + final Head head, final Can<ManagedObject> arguments, final InteractionInitiatedBy interactionInitiatedBy, final Where where) { + val target = head.getOwner(); + // see it? final Consent visibility = isVisible(target, interactionInitiatedBy, where); if (visibility.isVetoed()) { @@ -412,7 +413,7 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA throw new RecoverableException(validity.getReason()); } - return execute(target, mixedInAdapter, arguments, interactionInitiatedBy); + return execute(head, arguments, interactionInitiatedBy); } /** @@ -420,41 +421,38 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA * {@link #executeInternal(ManagedObject, ManagedObject, List, InteractionInitiatedBy) executeInternal} * to invoke the {@link ActionInvocationFacet invocation facet}. * - * @param mixedInAdapter - will be null for regular actions, and for mixin actions. When a mixin action invokes its underlying mixedIn action, then will be populated (so that the ActionDomainEvent can correctly provide the underlying mixin) + * @param mixedInAdapter - will be null for regular actions, and for mixin actions. + * When a mixin action invokes its underlying mixedIn action, then will be populated + * (so that the ActionDomainEvent can correctly provide the underlying mixin) */ @Override public ManagedObject execute( - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + final Head head, final Can<ManagedObject> argumentAdapters, final InteractionInitiatedBy interactionInitiatedBy) { - setupCommand(targetAdapter, argumentAdapters); - - return this.executeInternal(targetAdapter, mixedInAdapter, argumentAdapters, interactionInitiatedBy); + setupCommand(head.getTarget(), argumentAdapters); + + return this.executeInternal(head, argumentAdapters, interactionInitiatedBy); } /** - * private API, called by mixins and contributees. + * private API, called by mixins */ - public ManagedObject executeInternal( - final ManagedObject targetAdapter, - final ManagedObject mixedInAdapter, + protected ManagedObject executeInternal( + final Head head, final Can<ManagedObject> argumentAdapters, final InteractionInitiatedBy interactionInitiatedBy) { val actionInvocationFacet = getFacet(ActionInvocationFacet.class); return actionInvocationFacet - .invoke(this, targetAdapter, mixedInAdapter, argumentAdapters, interactionInitiatedBy); + .invoke(this, head, argumentAdapters, interactionInitiatedBy); } protected ActionInvocationFacet getActionInvocationFacet() { return getFacetedMethod().getFacet(ActionInvocationFacet.class); } - - - // -- defaults @Override diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java index 25ba9d1..da2ca53 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java @@ -22,21 +22,17 @@ import java.util.List; import org.apache.isis.applib.Identifier; import org.apache.isis.core.commons.collections.Can; +import org.apache.isis.core.commons.internal.assertions._Assert; import org.apache.isis.core.commons.internal.base._Strings; -import org.apache.isis.core.commons.internal.collections._Lists; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.facetapi.FacetHolder; import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl; import org.apache.isis.core.metamodel.facetapi.FacetUtil; -import org.apache.isis.core.metamodel.facetapi.FeatureType; -import org.apache.isis.core.metamodel.facets.FacetedMethodParameter; -import org.apache.isis.core.metamodel.facets.TypedHolder; import org.apache.isis.core.metamodel.facets.all.named.NamedFacetInferred; import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.spec.feature.ObjectAction; -import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter; import lombok.Getter; import lombok.NonNull; @@ -65,11 +61,6 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM @Getter(onMethod = @__(@Override)) private final FacetHolder facetHolder = new FacetHolderImpl(); - /** - * Lazily initialized by {@link #getParameters()} (so don't use directly!) - */ - private Can<ObjectActionParameter> parameters; - private final Identifier identifier; public ObjectActionMixedIn( @@ -102,9 +93,9 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM } @Override - protected Head headFor(final ManagedObject mixedInAdapter) { - val mixinAdapter = mixinAdapterFor(mixinType, mixedInAdapter); - return Head.of(mixedInAdapter, mixinAdapter); + protected Head headFor(final ManagedObject owner) { + val target = mixinAdapterFor(mixinType, owner); + return Head.of(owner, target); } @Override @@ -140,36 +131,6 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM public PendingParameterModelHead newPendingParameterModelHead(@NonNull ManagedObject actionOwner) { return PendingParameterModelHead.of(this, actionOwner, mixinAdapterFor(actionOwner)); } -// -// @Override -// protected synchronized Can<ObjectActionParameter> determineParameters() { -// if (parameters != null) { -// // because possible race condition (caller isn't synchronized) -// return parameters; -// } -// val mixinActionParameters = mixinAction.getParameters(); -// final List<FacetedMethodParameter> paramPeers = getFacetedMethod().getParameters(); -// -// final List<ObjectActionParameter> mixedInParameters = _Lists.newArrayList(); -// -// for(int paramIndex = 0; paramIndex < mixinActionParameters.size(); paramIndex++) { -// -// val mixinParameter = -// (ObjectActionParameterAbstract) mixinActionParameters.getElseFail(paramIndex); -// -// final TypedHolder paramPeer = paramPeers.get(paramIndex); -// getSpecificationLoader().loadSpecification(paramPeer.getType()); -// -// final ObjectActionParameterMixedIn mixedInParameter = -// mixinParameter.getPeer().getFeatureType() == FeatureType.ACTION_PARAMETER_SCALAR -// ? new OneToOneActionParameterMixedIn(mixinParameter, this) -// : new OneToManyActionParameterMixedIn(mixinParameter, this); -// mixedInParameters.add(mixedInParameter); -// } -// return Can.ofCollection(mixedInParameters); -// } -// - @Override public Can<ManagedObject> getDefaults(final ManagedObject mixedInAdapter) { @@ -191,19 +152,17 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM @Override public ManagedObject execute( - final ManagedObject target, // will be the mixedInAdapter - final ManagedObject mixedInAdapter, // will be passed in as null + final Head head, final Can<ManagedObject> arguments, final InteractionInitiatedBy interactionInitiatedBy) { - - final ManagedObject targetAdapter = mixinAdapterFor(mixinType, target); - final ManagedObject actualMixedInAdapter = target; - - setupCommand(actualMixedInAdapter, arguments); - + final ManagedObject owner = head.getOwner(); + final ManagedObject target = mixinAdapterFor(mixinType, owner); + _Assert.assertEquals(target.getSpecification(), head.getTarget().getSpecification()); + + setupCommand(head.getTarget(), arguments); return mixinAction.executeInternal( - targetAdapter, actualMixedInAdapter, arguments, + head, arguments, interactionInitiatedBy); } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java index 38b6ea1..55ee3db 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java @@ -56,6 +56,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction; import org.apache.isis.core.metamodel.spec.feature.ObjectMember; import org.apache.isis.schema.cmd.v2.CommandDto; +import lombok.NonNull; import lombok.val; public abstract class ObjectMemberAbstract @@ -244,13 +245,13 @@ implements ObjectMember, MetaModelContext.Delegating, FacetHolder.Delegating { * For mixins */ ManagedObject mixinAdapterFor( - final Class<?> mixinType, - final ManagedObject mixedInAdapter) { + @NonNull final Class<?> mixinType, + @NonNull final ManagedObject mixedInAdapter) { val spec = getSpecificationLoader().loadSpecification(mixinType); val mixinFacet = spec.getFacet(MixinFacet.class); - val mixinPojo = mixinFacet.instantiate(mixedInAdapter.getPojo()); - return ManagedObject.of(spec, mixinPojo); + val mixinPojo = mixinFacet.instantiate(Objects.requireNonNull(mixedInAdapter.getPojo())); + return ManagedObject.of(spec, Objects.requireNonNull(mixinPojo)); } static String determineNameFrom(final ObjectAction mixinAction) { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java index 909f37e..8e7cfbc 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java @@ -150,13 +150,12 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp @Override public ManagedObject get( - final ManagedObject mixedInAdapter, + final ManagedObject ownerAdapter, final InteractionInitiatedBy interactionInitiatedBy) { - final ManagedObject mixinAdapter = mixinAdapterFor(mixinType, mixedInAdapter); return getPublishingServiceInternal().withPublishingSuppressed( () -> mixinAction.executeInternal( - mixinAdapter, mixedInAdapter, Can.empty(), interactionInitiatedBy)); + headFor(ownerAdapter), Can.empty(), interactionInitiatedBy)); } @Override diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java index 7607079..af0f350 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.isis.applib.Identifier; import org.apache.isis.applib.annotation.Where; import org.apache.isis.core.commons.collections.Can; +import org.apache.isis.core.commons.internal.assertions._Assert; import org.apache.isis.core.commons.internal.base._Strings; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.facetapi.FacetHolder; @@ -137,11 +138,14 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple final ManagedObject mixedInAdapter, final InteractionInitiatedBy interactionInitiatedBy) { + val head = headFor(mixedInAdapter); + val mixinAdapter = mixinAdapterFor(mixinType, mixedInAdapter); + _Assert.assertEquals(mixedInAdapter, head.getMixedIn().orElse(null)); + return getPublisherDispatchService().withPublishingSuppressed( - () -> mixinAction.executeInternal( - mixinAdapter, mixedInAdapter, Can.empty(), interactionInitiatedBy) + () -> mixinAction.executeInternal(head, Can.empty(), interactionInitiatedBy) ); } diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java index 926ad19..c744d24 100644 --- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java +++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java @@ -54,6 +54,7 @@ import org.apache.isis.core.metamodel.adapter.oid.Oid; import org.apache.isis.core.metamodel.adapter.oid.RootOid; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.objectmanager.load.ObjectLoader; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.ObjectSpecification; @@ -189,8 +190,8 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { // it will switch the targetAdapter to be the mixedInAdapter transparently val argAdapters = argAdaptersFor(actionDto); - val resultAdapter = objectAction.execute( - targetAdapter, null, argAdapters, InteractionInitiatedBy.FRAMEWORK); + val resultAdapter = objectAction.execute(Head.simple(targetAdapter) + , argAdapters, InteractionInitiatedBy.FRAMEWORK); // flush any Isis PersistenceCommands pending // (else might get transient objects for the return value) diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java index 907ddb2..c451d1f 100644 --- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java +++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java @@ -51,6 +51,7 @@ import org.apache.isis.core.metamodel.facets.ImperativeFacet; import org.apache.isis.core.metamodel.facets.ImperativeFacet.Intent; import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet; import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacet; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.metamodel.objectmanager.ObjectManager; import org.apache.isis.core.metamodel.spec.ManagedObject; import org.apache.isis.core.metamodel.spec.ObjectSpecification; @@ -643,11 +644,12 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle }); return runExecutionTask(()->{ - val interactionInitiatedBy = getInteractionInitiatedBy(); - val mixedInAdapter = (ManagedObject)null; // if a mixin action, then it will automatically fill in. + val head2 = objectAction.newPendingParameterModelHead(targetAdapter); + val head = Head.of(head2.getActionOwner(), head2.getActionTarget()); + val returnedAdapter = objectAction.execute( - targetAdapter, mixedInAdapter, argAdapters, + head, argAdapters, interactionInitiatedBy); return ManagedObject.unwrapSingle(returnedAdapter); diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java index 500d6f0..abce573 100644 --- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java +++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/user/ApplicationUserRepository.java @@ -33,6 +33,7 @@ import org.apache.isis.applib.services.factory.FactoryService; import org.apache.isis.applib.services.queryresultscache.QueryResultsCache; import org.apache.isis.applib.services.repository.RepositoryService; import org.apache.isis.core.commons.internal.base._Casts; +import org.apache.isis.core.commons.internal.base._NullSafe; import org.apache.isis.core.commons.internal.collections._Sets; import org.apache.isis.core.commons.internal.exceptions._Exceptions; import org.apache.isis.extensions.secman.api.SecurityModuleConfig; @@ -137,8 +138,7 @@ implements org.apache.isis.extensions.secman.api.user.ApplicationUserRepository< org.apache.isis.extensions.secman.api.role.ApplicationRole genericRole) { val role = _Casts.<ApplicationRole>uncheckedCast(genericRole); - return role.getUsers() - .stream() + return _NullSafe.stream(role.getUsers()) .collect(_Sets.toUnmodifiableSorted()); } diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java index dd83715..2a09806 100644 --- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java +++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java @@ -34,6 +34,7 @@ import com.vaadin.flow.theme.lumo.Lumo; import org.apache.isis.core.commons.collections.Can; import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; import org.apache.isis.core.metamodel.context.MetaModelContext; +import org.apache.isis.core.metamodel.interactions.InteractionContext.Head; import org.apache.isis.core.webapp.context.IsisWebAppCommonContext; import org.apache.isis.incubator.viewer.vaadin.model.action.ActionVaa; import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentFactoryVaa; @@ -105,8 +106,7 @@ implements BeforeEnterObserver { val result = objectAction .execute( - actionOwner, - null, + Head.simple(actionOwner), Can.empty(), InteractionInitiatedBy.USER ); diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java index 14e5628..7ea5d51 100644 --- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java +++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ActionModel.java @@ -192,11 +192,12 @@ implements FormUiModel, FormExecutorContext { final Can<ManagedObject> arguments = argCache().snapshot(); final ObjectAction action = getMetaModel(); - // if this action is a mixin, then it will fill in the details automatically. - val mixedInAdapter = (ManagedObject)null; + val head2 = action.newPendingParameterModelHead(targetAdapter); + val head = Head.of(head2.getActionOwner(), head2.getActionTarget()); + val resultAdapter = action.executeWithRuleChecking( - targetAdapter, mixedInAdapter, arguments, + head, arguments, InteractionInitiatedBy.USER, WHERE_FOR_ACTION_INVOCATION);