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 c568147d62ed6f5519e61051cdc26c6ce4ff83ad Author: danhaywood <d...@haywood-associates.co.uk> AuthorDate: Thu Nov 22 13:37:08 2018 +0100 ISIS-2043: adds support for @DomainObject(xxxDomainEvent=...) for mixins whereby will honour the domain event specified if not otherwise annotated. In fact, this contains a few other fixes: * previously, although mixin actions did emit domain events for all phases (hide/disable/validate/executing/executed), mixin properties and mixin collections emitted none. Now this is fixed so that the emit domain events for the first two phases (hide/disable). It doesn't make sense to emit them for the remainder because mixin props/colls are always derived (are read-only queries under the covers). * also, getMixedIn() now promoted from ActionDomainEvent up to AbstractDomainEvent * also, added similar getSubject() (a simple wrapper around getSource() and getMixedIn()) also in AbstractDomainEvent. --- .../services/eventbus/AbstractDomainEvent.java | 35 ++++++ .../services/eventbus/ActionDomainEvent.java | 32 ----- .../core/metamodel/facets/DomainEventHelper.java | 13 ++ .../facets/SingleClassValueFacetAbstract.java | 2 +- .../invocation/ActionDomainEventFacetAbstract.java | 28 +++-- .../CollectionAnnotationFacetFactory.java | 9 +- ...ectionAddToFacetForDomainEventFromAbstract.java | 7 +- .../modify/CollectionDomainEventFacetAbstract.java | 42 ++++--- ...nRemoveFromFacetForDomainEventFromAbstract.java | 5 +- .../property/PropertyAnnotationFacetFactory.java | 6 +- .../modify/PropertyDomainEventFacetAbstract.java | 80 +++++++----- .../modify/PropertyDomainEventFacetDefault.java | 8 +- ...acetForPostsPropertyChangedEventAnnotation.java | 8 +- ...pertyDomainEventFacetForPropertyAnnotation.java | 8 +- ...EventFacetForPropertyInteractionAnnotation.java | 8 +- ...tySetterOrClearFacetForDomainEventAbstract.java | 10 +- .../param/DeriveFacetsPostProcessor.java | 137 +++++++++++++++++++++ 17 files changed, 334 insertions(+), 104 deletions(-) diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java index bba4e98..4e906ed 100644 --- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java +++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java @@ -52,6 +52,41 @@ public abstract class AbstractDomainEvent<S> extends java.util.EventObject { return source != null ? source : new Object(); } + + // region > mixedIn + private Object mixedIn; + + /** + * Populated only for mixins; holds the underlying domain object that the mixin contributes to. + */ + public Object getMixedIn() { + return mixedIn; + } + /** + * Not API - set by the framework. + */ + public void setMixedIn(final Object mixedIn) { + this.mixedIn = mixedIn; + } + // endregion + + + + // region > subject + + /** + * The subject of the event, which will be either the {@link #getSource() source} for a regular action, or the + * {@link #getMixedIn() mixed-in} domain object for a mixin. + */ + public Object getSubject() { + final Object mixedIn = getMixedIn(); + return mixedIn != null ? mixedIn : getSource(); + } + + + //endregion + + //region > Phase public enum Phase { diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java index 1d97fc2..385a43e 100644 --- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java +++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java @@ -193,38 +193,6 @@ public abstract class ActionDomainEvent<S> extends AbstractInteractionEvent<S> { //endregion - // region > mixedIn - private Object mixedIn; - - /** - * Populated only for mixins; holds the underlying domain object that the mixin contributes to. - */ - public Object getMixedIn() { - return mixedIn; - } - /** - * Not API - set by the framework. - */ - public void setMixedIn(final Object mixedIn) { - this.mixedIn = mixedIn; - } - // endregion - - - - // region > subject - - /** - * The subject of the event, which will be either the {@link #getSource() source} for a regular action, or the - * {@link #getMixedIn() mixed-in} domain object for a mixin. - */ - public Object getSubject() { - final Object mixedIn = getMixedIn(); - return mixedIn != null ? mixedIn : getSource(); - } - - - //endregion //region > arguments private List<Object> arguments; 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 772844c..f881113 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 @@ -192,6 +192,7 @@ public class DomainEventHelper { final PropertyDomainEvent<?, ?> existingEvent, final IdentifiedHolder identified, final ObjectAdapter targetAdapter, + final ObjectAdapter mixedInAdapter, final Object oldValue, final Object newValue) { @@ -206,6 +207,12 @@ public class DomainEventHelper { } else { // all other phases, create a new event event = newPropertyDomainEvent(eventType, identifier, source, oldValue, newValue); + + // copy over if have + if(mixedInAdapter != null ) { + event.setMixedIn(mixedInAdapter.getObject()); + } + } event.setEventPhase(phase); @@ -283,6 +290,7 @@ public class DomainEventHelper { final CollectionDomainEvent<?, ?> existingEvent, final IdentifiedHolder identified, final ObjectAdapter targetAdapter, + final ObjectAdapter mixedInAdapter, final CollectionDomainEvent.Of of, final Object reference) { try { @@ -295,6 +303,11 @@ public class DomainEventHelper { final Object source = ObjectAdapter.Util.unwrap(targetAdapter); final Identifier identifier = identified.getIdentifier(); event = newCollectionDomainEvent(eventType, phase, identifier, source, of, reference); + + // copy over if have + if(mixedInAdapter != null ) { + event.setMixedIn(mixedInAdapter.getObject()); + } } event.setEventPhase(phase); diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/SingleClassValueFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/SingleClassValueFacetAbstract.java index d057fcc..2c71129 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/SingleClassValueFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/SingleClassValueFacetAbstract.java @@ -62,7 +62,7 @@ public abstract class SingleClassValueFacetAbstract extends FacetAbstract implem @Override public void appendAttributesTo(final Map<String, Object> attributeMap) { super.appendAttributesTo(attributeMap); - attributeMap.put("value", value); + attributeMap.put("value", value()); } } 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 4399084..0763fb9 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 @@ -48,6 +48,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction; public abstract class ActionDomainEventFacetAbstract extends SingleClassValueFacetAbstract implements ActionDomainEventFacet { + private Class<? extends ActionDomainEvent<?>> eventType; private final TranslationService translationService; private final String translationContext; @@ -63,6 +64,7 @@ public abstract class ActionDomainEventFacetAbstract final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader) { super(type(), holder, eventType, specificationLoader); + this.eventType = eventType; this.translationService = servicesInjector.lookupService(TranslationService.class); // sadness: same as in TranslationFactory @@ -71,6 +73,23 @@ public abstract class ActionDomainEventFacetAbstract domainEventHelper = new DomainEventHelper(servicesInjector); } + @Override + public Class<?> value() { + return eventType; + } + + protected Class eventType() { + return eventType; + } + + public Class<? extends ActionDomainEvent<?>> getEventType() { + return eventType; + } + public void setEventType(final Class<? extends ActionDomainEvent<?>> eventType) { + this.eventType = eventType; + } + + @Override public String hides(final VisibilityContext<? extends VisibilityEvent> ic) { @@ -147,13 +166,4 @@ public abstract class ActionDomainEventFacetAbstract return null; } - protected Class eventType() { - return value(); - } - - public Class<? extends ActionDomainEvent<?>> getEventType() { - //noinspection unchecked - return eventType(); - } - } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java index 1832bda..1372406 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java @@ -117,6 +117,11 @@ public class CollectionAnnotationFacetFactory extends FacetFactoryAbstract imple return; } + + + // following only runs for regular collections, not for mixins. + // those are tackled in the post-processing, when more of the metamodel is available to us + // // Set up CollectionDomainEventFacet, which will act as the hiding/disabling/validating advisor // @@ -242,7 +247,7 @@ public class CollectionAnnotationFacetFactory extends FacetFactoryAbstract imple } - private static Class<? extends CollectionDomainEvent<?,?>> defaultFromDomainObjectIfRequired( + public static Class<? extends CollectionDomainEvent<?,?>> defaultFromDomainObjectIfRequired( final ObjectSpecification typeSpec, final Class<? extends CollectionDomainEvent<?,?>> collectionDomainEventType) { if (collectionDomainEventType == CollectionDomainEvent.Default.class) { @@ -382,6 +387,8 @@ public class CollectionAnnotationFacetFactory extends FacetFactoryAbstract imple } + + // ////////////////////////////////////// @Override 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 1b67a62..fe3927b 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 @@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.collections.collection.modify; import java.util.Map; import java.util.Set; + import org.apache.isis.applib.services.eventbus.AbstractDomainEvent; import org.apache.isis.applib.services.eventbus.CollectionDomainEvent; import org.apache.isis.core.metamodel.adapter.ObjectAdapter; @@ -33,7 +34,6 @@ import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToF import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.isis.core.metamodel.services.ServicesInjector; - public abstract class CollectionAddToFacetForDomainEventFromAbstract extends SingleValueFacetAbstract<Class<? extends CollectionDomainEvent<?,?>>> implements CollectionAddToFacet { @@ -86,13 +86,14 @@ public abstract class CollectionAddToFacetForDomainEventFromAbstract // either doesn't contain object, or doesn't have set semantics, so // execute the add wrapped between the executing and executed events ... + final ObjectAdapter mixedInAdapter = null; // ... post the executing event final CollectionDomainEvent<?, ?> event = domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTING, eventType(), null, - getIdentified(), targetAdapter, + getIdentified(), targetAdapter, mixedInAdapter, CollectionDomainEvent.Of.ADD_TO, referencedObject); @@ -103,7 +104,7 @@ public abstract class CollectionAddToFacetForDomainEventFromAbstract domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTED, value(), verify(event), - getIdentified(), targetAdapter, + getIdentified(), targetAdapter, mixedInAdapter, 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 75c227a..6569e78 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 @@ -50,6 +50,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader) { super(CollectionDomainEventFacet.class, holder, eventType, specificationLoader); + this.eventType = eventType; this.translationService = servicesInjector.lookupService(TranslationService.class); // sadness: same as in TranslationFactory @@ -58,6 +59,25 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper = new DomainEventHelper(servicesInjector); } + private Class<? extends CollectionDomainEvent<?, ?>> eventType; + + private Class<?> eventType() { + return value(); + } + + @Override + public Class<?> value() { + return eventType; + } + + public Class<? extends CollectionDomainEvent<?, ?>> getEventType() { + return eventType; + } + + public void setEventType(final Class<? extends CollectionDomainEvent<?, ?>> eventType) { + this.eventType = eventType; + } + @Override public String hides(final VisibilityContext<? extends VisibilityEvent> ic) { @@ -65,7 +85,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.HIDE, eventType(), null, - getIdentified(), ic.getTarget(), + getIdentified(), ic.getTarget(), ic.getMixedIn(), CollectionDomainEvent.Of.ACCESS, null); if (event != null && event.isHidden()) { @@ -81,7 +101,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.DISABLE, eventType(), null, - getIdentified(), ic.getTarget(), + getIdentified(), ic.getTarget(), ic.getMixedIn(), CollectionDomainEvent.Of.ACCESS, null); if (event != null && event.isDisabled()) { @@ -97,6 +117,10 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu @Override public String invalidates(final ValidityContext<? extends ValidityEvent> ic) { + // if this is a mixin, then this ain't true. + if(!(ic instanceof ProposedHolder)) { + return null; + } final ProposedHolder catc = (ProposedHolder) ic; final Object proposed = catc.getProposed().getObject(); @@ -109,7 +133,7 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.VALIDATE, eventType(), null, - getIdentified(), ic.getTarget(), + getIdentified(), ic.getTarget(), ic.getMixedIn(), of, proposed); if (event != null && event.isInvalid()) { @@ -123,16 +147,4 @@ public abstract class CollectionDomainEventFacetAbstract extends SingleClassValu return null; } - private Class<?> eventType() { - return value(); - } - - /** - * For testing. - */ - public Class<? extends CollectionDomainEvent<?, ?>> getEventType() { - Class eventType = eventType(); - return eventType; - } - } 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 1418f84..95ef179 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 @@ -86,13 +86,14 @@ public abstract class CollectionRemoveFromFacetForDomainEventFromAbstract // contains the element, so // execute the remove wrapped between the executing and executed events ... + final ObjectAdapter mixedInAdapter = null; // ... post the executing event final CollectionDomainEvent<?, ?> event = domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTING, eventType(), null, - getIdentified(), targetAdapter, + getIdentified(), targetAdapter, null, CollectionDomainEvent.Of.REMOVE_FROM, referencedObject); @@ -103,7 +104,7 @@ public abstract class CollectionRemoveFromFacetForDomainEventFromAbstract domainEventHelper.postEventForCollection( AbstractDomainEvent.Phase.EXECUTED, value(), verify(event), - getIdentified(), targetAdapter, + getIdentified(), targetAdapter, mixedInAdapter, CollectionDomainEvent.Of.REMOVE_FROM, referencedObject); } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java index 47db77a..d7869dc 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java @@ -146,6 +146,10 @@ public class PropertyAnnotationFacetFactory extends FacetFactoryAbstract impleme return; } + // following only runs for regular properties, not for mixins. + // those are tackled in the post-processing, when more of the metamodel is available to us + + // // Set up PropertyDomainEventFacet, which will act as the hiding/disabling/validating advisor // @@ -259,7 +263,7 @@ public class PropertyAnnotationFacetFactory extends FacetFactoryAbstract impleme } } - private static Class<? extends PropertyDomainEvent<?,?>> defaultFromDomainObjectIfRequired( + public static Class<? extends PropertyDomainEvent<?,?>> defaultFromDomainObjectIfRequired( final ObjectSpecification typeSpec, final Class<? extends PropertyDomainEvent<?,?>> propertyDomainEventType) { if (propertyDomainEventType == PropertyDomainEvent.Default.class) { 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 4857840..4b00586 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 @@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.properties.property.modify; import java.util.Map; +import org.apache.isis.applib.annotation.DomainObject; import org.apache.isis.applib.events.UsabilityEvent; import org.apache.isis.applib.events.ValidityEvent; import org.apache.isis.applib.events.VisibilityEvent; @@ -40,24 +41,29 @@ import org.apache.isis.core.metamodel.interactions.ValidityContext; import org.apache.isis.core.metamodel.interactions.VisibilityContext; import org.apache.isis.core.metamodel.services.ServicesInjector; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn; public abstract class PropertyDomainEventFacetAbstract extends SingleClassValueFacetAbstract implements PropertyDomainEventFacet { private final DomainEventHelper domainEventHelper; - private final PropertyOrCollectionAccessorFacet getterFacet; + private final PropertyOrCollectionAccessorFacet getterFacetIfAny; private final TranslationService translationService; private final String translationContext; + /** + * @param getterFacetIfAny - will be null if this is for a mixin {@link OneToOneAssociationMixedIn}. + */ public PropertyDomainEventFacetAbstract( final Class<? extends PropertyDomainEvent<?, ?>> eventType, - final PropertyOrCollectionAccessorFacet getterFacet, + final PropertyOrCollectionAccessorFacet getterFacetIfAny, final FacetHolder holder, final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader) { super(PropertyDomainEventFacet.class, holder, eventType, specificationLoader); - this.getterFacet = getterFacet; + this.eventType = eventType; + this.getterFacetIfAny = getterFacetIfAny; this.translationService = servicesInjector.lookupService(TranslationService.class); // sadness: same as in TranslationFactory @@ -66,6 +72,29 @@ public abstract class PropertyDomainEventFacetAbstract domainEventHelper = new DomainEventHelper(servicesInjector); } + private Class<? extends PropertyDomainEvent<?, ?>> eventType; + + @Override + public Class<?> value() { + return eventType; + } + + private Class<?> eventType() { + return eventType; + } + + public Class<? extends PropertyDomainEvent<?, ?>> getEventType() { + return eventType; + } + + /** + * Can be overwritten if this facet is on a mixin where the subject (mixedInType) is annotated with + * {@link DomainObject#propertyDomainEvent()}. + */ + public void setEventType(final Class<? extends PropertyDomainEvent<?, ?>> eventType) { + this.eventType = eventType; + } + @Override public String hides(VisibilityContext<? extends VisibilityEvent> ic) { @@ -73,7 +102,7 @@ public abstract class PropertyDomainEventFacetAbstract domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.HIDE, eventType(), null, - getIdentified(), ic.getTarget(), + getIdentified(), ic.getTarget(), ic.getMixedIn(), null, null); if (event != null && event.isHidden()) { return "Hidden by subscriber"; @@ -88,7 +117,7 @@ public abstract class PropertyDomainEventFacetAbstract domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.DISABLE, eventType(), null, - getIdentified(), ic.getTarget(), + getIdentified(), ic.getTarget(), ic.getMixedIn(), null, null); if (event != null && event.isDisabled()) { final TranslatableString reasonTranslatable = event.getDisabledReasonTranslatable(); @@ -103,15 +132,25 @@ public abstract class PropertyDomainEventFacetAbstract @Override public String invalidates(ValidityContext<? extends ValidityEvent> ic) { - final Object oldValue = getterFacet.getProperty(ic.getTarget(), - ic.getInitiatedBy()); - final Object proposedValue = proposedFrom(ic); + if(getterFacetIfAny == null) { + return null; + } + + // if this is a mixin, then this ain't true. + if(!(ic instanceof ProposedHolder)) { + return null; + } + final ProposedHolder ph = (ProposedHolder) ic; + + final Object oldValue = getterFacetIfAny.getProperty(ic.getTarget(), ic.getInitiatedBy()); + final ObjectAdapter proposedAdapter = ph.getProposed(); + final Object proposedValue = proposedAdapter != null ? proposedAdapter.getObject() : null; final PropertyDomainEvent<?, ?> event = domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.VALIDATE, eventType(), null, - getIdentified(), ic.getTarget(), + getIdentified(), ic.getTarget(), ic.getMixedIn(), oldValue, proposedValue); if (event != null && event.isInvalid()) { final TranslatableString reasonTranslatable = event.getInvalidityReasonTranslatable(); @@ -124,27 +163,10 @@ public abstract class PropertyDomainEventFacetAbstract return null; } - private static Object proposedFrom(ValidityContext<? extends ValidityEvent> ic) { - final ProposedHolder ph = (ProposedHolder) ic; - final ObjectAdapter proposedAdapter = ph.getProposed(); - return proposedAdapter != null? proposedAdapter.getObject(): null; - } - - private Class<?> eventType() { - return value(); - } - - /** - * For testing. - */ - public Class<? extends PropertyDomainEvent<?, ?>> getEventType() { - Class eventType = eventType(); - return eventType; - } - - @Override public void appendAttributesTo(final Map<String, Object> attributeMap) { + @Override + public void appendAttributesTo(final Map<String, Object> attributeMap) { super.appendAttributesTo(attributeMap); - attributeMap.put("getterFacet", getterFacet); + attributeMap.put("getterFacet", getterFacetIfAny); } } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetDefault.java index 43cb32d..f228dbd 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetDefault.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetDefault.java @@ -24,14 +24,18 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder; import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.isis.core.metamodel.services.ServicesInjector; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn; public class PropertyDomainEventFacetDefault extends PropertyDomainEventFacetAbstract { + /** + * @param getterFacetIfAny - will be null if this is for a mixin {@link OneToOneAssociationMixedIn}. + */ public PropertyDomainEventFacetDefault( final Class<? extends PropertyDomainEvent<?, ?>> eventType, - final PropertyOrCollectionAccessorFacet getterFacet, + final PropertyOrCollectionAccessorFacet getterFacetIfAny, final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader, final FacetHolder holder) { - super(eventType, getterFacet, holder, servicesInjector, specificationLoader); + super(eventType, getterFacetIfAny, holder, servicesInjector, specificationLoader); } } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPostsPropertyChangedEventAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPostsPropertyChangedEventAnnotation.java index d848833..bae3f46 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPostsPropertyChangedEventAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPostsPropertyChangedEventAnnotation.java @@ -24,6 +24,7 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder; import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.isis.core.metamodel.services.ServicesInjector; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn; /** * @deprecated @@ -31,11 +32,14 @@ import org.apache.isis.core.metamodel.specloader.SpecificationLoader; @Deprecated public class PropertyDomainEventFacetForPostsPropertyChangedEventAnnotation extends PropertyDomainEventFacetAbstract { + /** + * @param getterFacetIfAny - will be null if this is for a mixin {@link OneToOneAssociationMixedIn}. + */ public PropertyDomainEventFacetForPostsPropertyChangedEventAnnotation( final Class<? extends PropertyDomainEvent<?, ?>> eventType, - final PropertyOrCollectionAccessorFacet getterFacet, + final PropertyOrCollectionAccessorFacet getterFacetIfAny, final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader, final FacetHolder holder) { - super(eventType, getterFacet, holder, servicesInjector, specificationLoader); + super(eventType, getterFacetIfAny, holder, servicesInjector, specificationLoader); } } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyAnnotation.java index a31c90a..b731d35 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyAnnotation.java @@ -24,14 +24,18 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder; import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.isis.core.metamodel.services.ServicesInjector; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn; public class PropertyDomainEventFacetForPropertyAnnotation extends PropertyDomainEventFacetAbstract { + /** + * @param getterFacetIfAny - will be null if this is for a mixin {@link OneToOneAssociationMixedIn}. + */ public PropertyDomainEventFacetForPropertyAnnotation( final Class<? extends PropertyDomainEvent<?, ?>> eventType, - final PropertyOrCollectionAccessorFacet getterFacet, + final PropertyOrCollectionAccessorFacet getterFacetIfAny, final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader, final FacetHolder holder) { - super(eventType, getterFacet, holder, servicesInjector, specificationLoader); + super(eventType, getterFacetIfAny, holder, servicesInjector, specificationLoader); } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyInteractionAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyInteractionAnnotation.java index 1e49c31..26e812d 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyInteractionAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacetForPropertyInteractionAnnotation.java @@ -24,6 +24,7 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder; import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.isis.core.metamodel.services.ServicesInjector; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn; /** * @deprecated @@ -31,11 +32,14 @@ import org.apache.isis.core.metamodel.specloader.SpecificationLoader; @Deprecated public class PropertyDomainEventFacetForPropertyInteractionAnnotation extends PropertyDomainEventFacetAbstract { + /** + * @param getterFacetIfAny - will be null if this is for a mixin {@link OneToOneAssociationMixedIn}. + */ public PropertyDomainEventFacetForPropertyInteractionAnnotation( final Class<? extends PropertyDomainEvent<?, ?>> eventType, - final PropertyOrCollectionAccessorFacet getterFacet, + final PropertyOrCollectionAccessorFacet getterFacetIfAny, final ServicesInjector servicesInjector, final SpecificationLoader specificationLoader, final FacetHolder holder) { - super(eventType, getterFacet, holder, servicesInjector, specificationLoader); + super(eventType, getterFacetIfAny, holder, servicesInjector, specificationLoader); } } 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 fd44952..1fd5017 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 @@ -139,6 +139,7 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract final ObjectAdapter targetAdapter, final InteractionInitiatedBy interactionInitiatedBy) { + final ObjectAdapter mixedInAdapter = null; setOrClearProperty(Style.CLEAR, owningProperty, targetAdapter, null, interactionInitiatedBy); @@ -150,6 +151,7 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract final ObjectAdapter newValueAdapter, final InteractionInitiatedBy interactionInitiatedBy) { + final ObjectAdapter mixedInAdapter = null; setOrClearProperty(Style.SET, owningProperty, targetAdapter, newValueAdapter, interactionInitiatedBy); @@ -162,11 +164,12 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract final ObjectAdapter newValueAdapter, final InteractionInitiatedBy interactionInitiatedBy) { + final ObjectAdapter mixedInAdapter = null; getPersistenceSessionServiceInternal().executeWithinTransaction( new TransactionalClosure(){ @Override public void execute() { - doSetOrClearProperty(style, owningProperty, targetAdapter, newValueAdapter, interactionInitiatedBy); + doSetOrClearProperty(style, owningProperty, targetAdapter, mixedInAdapter, newValueAdapter, interactionInitiatedBy); } } ); @@ -179,6 +182,7 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract final Style style, final OneToOneAssociation owningProperty, final ObjectAdapter targetAdapter, + final ObjectAdapter mixedInAdapter, final ObjectAdapter newValueAdapter, final InteractionInitiatedBy interactionInitiatedBy) { @@ -250,7 +254,7 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.EXECUTING, eventType(), null, - getIdentified(), targetAdapter, + getIdentified(), targetAdapter, mixedInAdapter, oldValue, newValue); @@ -271,7 +275,7 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract domainEventHelper.postEventForProperty( AbstractDomainEvent.Phase.EXECUTED, eventType(), verify(event), - getIdentified(), targetAdapter, + getIdentified(), targetAdapter, mixedInAdapter, oldValue, actualNewValue); } diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/DeriveFacetsPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/DeriveFacetsPostProcessor.java index 0d70429..8c390b2 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/DeriveFacetsPostProcessor.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/DeriveFacetsPostProcessor.java @@ -19,22 +19,35 @@ package org.apache.isis.core.metamodel.postprocessors.param; +import java.lang.reflect.Method; import java.util.List; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import org.apache.isis.applib.annotation.Collection; +import org.apache.isis.applib.annotation.Property; import org.apache.isis.applib.filter.Filters; +import org.apache.isis.applib.services.eventbus.ActionDomainEvent; +import org.apache.isis.applib.services.eventbus.CollectionDomainEvent; +import org.apache.isis.applib.services.eventbus.PropertyDomainEvent; import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider; import org.apache.isis.core.metamodel.deployment.DeploymentCategory; import org.apache.isis.core.metamodel.deployment.DeploymentCategoryProvider; import org.apache.isis.core.metamodel.facetapi.Facet; import org.apache.isis.core.metamodel.facetapi.FacetUtil; +import org.apache.isis.core.metamodel.facets.Annotations; import org.apache.isis.core.metamodel.facets.FacetedMethod; import org.apache.isis.core.metamodel.facets.TypedHolder; +import org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionDomainEventFacet; +import org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionDomainEventFacetAbstract; import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet; import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet; +import org.apache.isis.core.metamodel.facets.collections.collection.CollectionAnnotationFacetFactory; +import org.apache.isis.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacet; +import org.apache.isis.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacetAbstract; +import org.apache.isis.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacetForCollectionAnnotation; import org.apache.isis.core.metamodel.facets.collections.disabled.fromimmutable.DisabledFacetOnCollectionDerivedFromImmutable; import org.apache.isis.core.metamodel.facets.collections.disabled.fromimmutable.DisabledFacetOnCollectionDerivedFromImmutableFactory; import org.apache.isis.core.metamodel.facets.members.describedas.annotprop.DescribedAsFacetOnMemberDerivedFromType; @@ -42,6 +55,9 @@ import org.apache.isis.core.metamodel.facets.members.describedas.annotprop.Descr import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacet; import org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetAbstract; import org.apache.isis.core.metamodel.facets.object.defaults.DefaultedFacet; +import org.apache.isis.core.metamodel.facets.object.domainobject.domainevents.ActionDomainEventDefaultFacetForDomainObjectAnnotation; +import org.apache.isis.core.metamodel.facets.object.domainobject.domainevents.CollectionDomainEventDefaultFacetForDomainObjectAnnotation; +import org.apache.isis.core.metamodel.facets.object.domainobject.domainevents.PropertyDomainEventDefaultFacetForDomainObjectAnnotation; import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet; import org.apache.isis.core.metamodel.facets.object.immutable.immutableannot.CopyImmutableFacetOntoMembersFactory; import org.apache.isis.core.metamodel.facets.object.recreatable.DisabledFacetOnCollectionDerivedFromRecreatableObject; @@ -60,6 +76,7 @@ import org.apache.isis.core.metamodel.facets.param.describedas.annotderived.Desc import org.apache.isis.core.metamodel.facets.param.describedas.annotderived.DescribedAsFacetOnParameterDerivedFromType; import org.apache.isis.core.metamodel.facets.param.typicallen.fromtype.TypicalLengthFacetOnParameterDerivedFromType; import org.apache.isis.core.metamodel.facets.param.typicallen.fromtype.TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory; +import org.apache.isis.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet; import org.apache.isis.core.metamodel.facets.properties.choices.enums.PropertyChoicesFacetDerivedFromChoicesFacet; import org.apache.isis.core.metamodel.facets.properties.choices.enums.PropertyChoicesFacetDerivedFromChoicesFacetFactory; @@ -68,6 +85,10 @@ import org.apache.isis.core.metamodel.facets.properties.defaults.fromtype.Proper import org.apache.isis.core.metamodel.facets.properties.defaults.fromtype.PropertyDefaultFacetDerivedFromTypeFactory; import org.apache.isis.core.metamodel.facets.properties.disabled.fromimmutable.DisabledFacetOnPropertyDerivedFromImmutable; import org.apache.isis.core.metamodel.facets.properties.disabled.fromimmutable.DisabledFacetOnPropertyDerivedFromImmutableFactory; +import org.apache.isis.core.metamodel.facets.properties.property.PropertyAnnotationFacetFactory; +import org.apache.isis.core.metamodel.facets.properties.property.modify.PropertyDomainEventFacet; +import org.apache.isis.core.metamodel.facets.properties.property.modify.PropertyDomainEventFacetAbstract; +import org.apache.isis.core.metamodel.facets.properties.property.modify.PropertyDomainEventFacetForPropertyAnnotation; import org.apache.isis.core.metamodel.facets.properties.typicallen.fromtype.TypicalLengthFacetOnPropertyDerivedFromType; import org.apache.isis.core.metamodel.facets.properties.typicallen.fromtype.TypicalLengthFacetOnPropertyDerivedFromTypeFacetFactory; import org.apache.isis.core.metamodel.progmodel.ObjectSpecificationPostProcessor; @@ -84,8 +105,11 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectMember; import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation; import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionMixedIn; import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionParameterAbstract; import org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToManyAssociationMixedIn; +import org.apache.isis.core.metamodel.specloader.specimpl.OneToOneAssociationMixedIn; /** * Sets up all the {@link Facet}s for an action in a single shot. @@ -97,6 +121,7 @@ public class DeriveFacetsPostProcessor implements ObjectSpecificationPostProcess private SpecificationLoader specificationLoader; private AuthenticationSessionProvider authenticationSessionProvider; private PersistenceSessionServiceInternal adapterManager; + private ServicesInjector servicesInjector; @Override public void postProcess(final ObjectSpecification objectSpecification) { @@ -112,6 +137,7 @@ public class DeriveFacetsPostProcessor implements ObjectSpecificationPostProcess final List<OneToOneAssociation> properties = objectSpecification.getProperties(Contributed.INCLUDED); // for each action, ... + for (final ObjectAction objectAction : objectActions) { // ... for each action parameter @@ -131,6 +157,7 @@ public class DeriveFacetsPostProcessor implements ObjectSpecificationPostProcess // corresponds to CopyImmutableFacetOntoMembersFactory. However, ImmutableFacet only ever disables for // properties and collections, so no point in copying over. + tweakActionDomainEventForMixin(objectSpecification, objectAction); } // for each property, ... @@ -142,6 +169,7 @@ public class DeriveFacetsPostProcessor implements ObjectSpecificationPostProcess derivePropertyDisabledFromViewModel(property); derivePropertyOrCollectionImmutableFromSpec(property); derivePropertyDisabledFromImmutable(property); + tweakPropertyMixinDomainEvent(objectSpecification, property); } @@ -198,6 +226,109 @@ public class DeriveFacetsPostProcessor implements ObjectSpecificationPostProcess addCollectionParamChoicesFacetIfNoneAlready(collection, scalarParam); } } + + deriveCollectionDomainEventForMixins(objectSpecification, collection); + } + } + + private void tweakActionDomainEventForMixin( + final ObjectSpecification objectSpecification, + final ObjectAction objectAction) { + if(objectAction instanceof ObjectActionMixedIn) { + // unlike collection and property mixins, there is no need to create the DomainEventFacet, it will + // have been created in the ActionAnnotationFacetFactory + final ActionDomainEventDefaultFacetForDomainObjectAnnotation actionDomainEventDefaultFacet = + objectSpecification.getFacet(ActionDomainEventDefaultFacetForDomainObjectAnnotation.class); + + if(actionDomainEventDefaultFacet != null) { + final ObjectActionMixedIn actionMixedIn = (ObjectActionMixedIn) objectAction; + final ActionDomainEventFacet actionFacet = actionMixedIn.getFacet(ActionDomainEventFacet.class); + if (actionFacet instanceof ActionDomainEventFacetAbstract) { + final ActionDomainEventFacetAbstract facetAbstract = (ActionDomainEventFacetAbstract) actionFacet; + if (facetAbstract.getEventType() == ActionDomainEvent.Default.class) { + final ActionDomainEventFacetAbstract existing = (ActionDomainEventFacetAbstract) actionFacet; + existing.setEventType(actionDomainEventDefaultFacet.getEventType()); + } + } + } + } + } + + private void deriveCollectionDomainEventForMixins( + final ObjectSpecification objectSpecification, + final OneToManyAssociation collection) { + + if(collection instanceof OneToManyAssociationMixedIn) { + final OneToManyAssociationMixedIn collectionMixin = (OneToManyAssociationMixedIn) collection; + final FacetedMethod facetedMethod = collectionMixin.getFacetedMethod(); + final Method method = facetedMethod != null ? facetedMethod.getMethod() : null; + + if(method != null) { + // this is basically a subset of the code that is in CollectionAnnotationFacetFactory, + // ignoring stuff which is deprecated for Isis v2 + final Collection collectionAnnot = Annotations.getAnnotation(method, Collection.class); + if(collectionAnnot != null) { + final Class<? extends CollectionDomainEvent<?, ?>> collectionDomainEventType = + CollectionAnnotationFacetFactory.defaultFromDomainObjectIfRequired( + objectSpecification, collectionAnnot.domainEvent()); + final CollectionDomainEventFacetForCollectionAnnotation collectionDomainEventFacet = new CollectionDomainEventFacetForCollectionAnnotation( + collectionDomainEventType, servicesInjector, specificationLoader, collection); + FacetUtil.addFacet(collectionDomainEventFacet); + } + + final CollectionDomainEventDefaultFacetForDomainObjectAnnotation collectionDomainEventDefaultFacet = + objectSpecification.getFacet(CollectionDomainEventDefaultFacetForDomainObjectAnnotation.class); + if(collectionDomainEventDefaultFacet != null) { + final CollectionDomainEventFacet collectionFacet = collection.getFacet(CollectionDomainEventFacet.class); + if (collectionFacet instanceof CollectionDomainEventFacetAbstract) { + final CollectionDomainEventFacetAbstract facetAbstract = (CollectionDomainEventFacetAbstract) collectionFacet; + if (facetAbstract.getEventType() == CollectionDomainEvent.Default.class) { + final CollectionDomainEventFacetAbstract existing = (CollectionDomainEventFacetAbstract) collectionFacet; + existing.setEventType(collectionDomainEventDefaultFacet.getEventType()); + } + } + } + } + } + } + + private void tweakPropertyMixinDomainEvent( + final ObjectSpecification objectSpecification, + final OneToOneAssociation property) { + + if(property instanceof OneToOneAssociationMixedIn) { + final OneToOneAssociationMixedIn propertyMixin = (OneToOneAssociationMixedIn) property; + final FacetedMethod facetedMethod = propertyMixin.getFacetedMethod(); + final Method method = facetedMethod != null ? facetedMethod.getMethod() : null; + + if(method != null) { + // this is basically a subset of the code that is in CollectionAnnotationFacetFactory, + // ignoring stuff which is deprecated for Isis v2 + final Property propertyAnnot = Annotations.getAnnotation(method, Property.class); + if(propertyAnnot != null) { + final Class<? extends PropertyDomainEvent<?, ?>> propertyDomainEventType = + PropertyAnnotationFacetFactory.defaultFromDomainObjectIfRequired( + objectSpecification, propertyAnnot.domainEvent()); + final PropertyOrCollectionAccessorFacet getterFacetIfAny = null; + final PropertyDomainEventFacetForPropertyAnnotation propertyDomainEventFacet = + new PropertyDomainEventFacetForPropertyAnnotation( + propertyDomainEventType, getterFacetIfAny, + servicesInjector, specificationLoader, property); + FacetUtil.addFacet(propertyDomainEventFacet); + } + } + final PropertyDomainEventDefaultFacetForDomainObjectAnnotation propertyDomainEventDefaultFacet = + objectSpecification.getFacet(PropertyDomainEventDefaultFacetForDomainObjectAnnotation.class); + if(propertyDomainEventDefaultFacet != null) { + final PropertyDomainEventFacet propertyFacet = property.getFacet(PropertyDomainEventFacet.class); + if (propertyFacet instanceof PropertyDomainEventFacetAbstract) { + final PropertyDomainEventFacetAbstract facetAbstract = (PropertyDomainEventFacetAbstract) propertyFacet; + if (facetAbstract.getEventType() == PropertyDomainEvent.Default.class) { + final PropertyDomainEventFacetAbstract existing = (PropertyDomainEventFacetAbstract) propertyFacet; + existing.setEventType(propertyDomainEventDefaultFacet.getEventType()); + } + } + } } } @@ -498,10 +629,16 @@ public class DeriveFacetsPostProcessor implements ObjectSpecificationPostProcess @Override public void setServicesInjector(final ServicesInjector servicesInjector) { + this.servicesInjector = servicesInjector; deploymentCategoryProvider = servicesInjector.getDeploymentCategoryProvider(); specificationLoader = servicesInjector.getSpecificationLoader(); authenticationSessionProvider = servicesInjector.getAuthenticationSessionProvider(); adapterManager = servicesInjector.getPersistenceSessionServiceInternal(); } + private ServicesInjector getServicesInjector() { + return servicesInjector; + } + + }