You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/10/27 11:30:34 UTC
[isis] branch master updated: ISIS-3265: init event sources only lazily
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 aecc7a3a92 ISIS-3265: init event sources only lazily
aecc7a3a92 is described below
commit aecc7a3a92855ce7ea1f8eba280e3b555b6cb015
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Oct 27 13:30:26 2022 +0200
ISIS-3265: init event sources only lazily
- don't fetch entities if not used
---
.../causeway/applib/events/EventObjectBase.java | 78 ++++++++++++++--------
.../events/lifecycle/ObjectCreatedEvent.java | 2 +-
.../core/metamodel/facets/DomainEventHelper.java | 19 ++----
.../facets/object/callbacks/CallbackFacet.java | 22 +-----
...ObjectLayoutAnnotationUsingCssClassUiEvent.java | 22 ++----
...mainObjectLayoutAnnotationUsingIconUiEvent.java | 23 ++-----
...inObjectLayoutAnnotationUsingLayoutUiEvent.java | 25 ++-----
...ainObjectLayoutAnnotationUsingTitleUiEvent.java | 30 ++-------
.../core/metamodel/object/MmEntityUtil.java | 11 +++
.../publish/LifecycleCallbackNotifier.java | 63 +++++++++--------
10 files changed, 125 insertions(+), 170 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/events/EventObjectBase.java b/api/applib/src/main/java/org/apache/causeway/applib/events/EventObjectBase.java
index 3afd67bdbb..407a014c42 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/events/EventObjectBase.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/events/EventObjectBase.java
@@ -18,62 +18,88 @@
*/
package org.apache.causeway.applib.events;
+import java.util.Optional;
+import java.util.function.Supplier;
+
import org.springframework.lang.Nullable;
-import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.commons.functional.Try;
+import org.apache.causeway.commons.internal.base._Casts;
+import org.apache.causeway.commons.internal.reflection._Reflect;
-import lombok.NonNull;
+import static org.apache.causeway.commons.internal.reflection._Reflect.Filter.paramCount;
/**
* @since 2.0 {@index}
*/
public abstract class EventObjectBase<T> {
+ // -- FACTORIES
+
/**
- * The object on which the Event initially occurred.
+ * Optionally returns a new event instance,
+ * based on whether the eventType has a public no-arg constructor.
+ * <p>
+ * Initializes the event's source with given {@code source}.
*/
- protected transient T source;
+ public static <T, E extends EventObjectBase<T>> Optional<E> getInstanceWithSource(
+ final Class<E> eventType, final T source) {
+ return getInstanceWithSourceSupplier(eventType, (Supplier<T>) ()->source);
+ }
/**
- * Constructs a prototypical Event.
- *
- * @param source The object on which the Event initially occurred.
+ * Optionally returns a new event instance,
+ * based on whether the eventType has a public no-arg constructor.
+ * <p>
+ * Initializes the event's source lazily, that is using given {@code eventSourceSupplier}.
*/
- protected EventObjectBase(final @Nullable T source) {
- this.source = source;
+ public static <T, E extends EventObjectBase<T>> Optional<E> getInstanceWithSourceSupplier(
+ final Class<E> eventType, final Supplier<T> eventSourceSupplier) {
+ return _Reflect.getPublicConstructors(eventType)
+ .filter(paramCount(0))
+ .getFirst()
+ .map(_Reflect::invokeConstructor)
+ .flatMap(Try::getValue)
+ .map(evnt->{
+ final E event = _Casts.uncheckedCast(evnt);
+ event.sourceSupplier = eventSourceSupplier;
+ return event;
+ });
}
+ // --
+
/**
- * The object on which the Event initially occurred.
+ * Provides the object on which the Event initially occurred.
+ */
+ protected transient Supplier<T> sourceSupplier = null;
+
+ /**
+ * Constructs a prototypical Event.
*
- * @return The object on which the Event initially occurred.
+ * @param source object on which the Event initially occurred (nullable)
*/
- public @Nullable T getSource() {
- return source;
+ protected EventObjectBase(final @Nullable T source) {
+ this.sourceSupplier = source!=null
+ ? ()->source
+ : null;
}
/**
- * A one-shot function. Only allowed to be called if a source has not already been set.
- *
- * @apiNote reserved for framework internal use
- *
- * @param source non-null
+ * Returns the object on which the Event initially occurred.
*/
- public void initSource(final @NonNull T source) {
- if(this.source!=null) {
- throw _Exceptions.illegalState(getClass().getName() + " cannot init when source is already set");
- }
- this.source = source;
+ public @Nullable T getSource() {
+ return sourceSupplier!=null
+ ? sourceSupplier.get()
+ : null;
}
/**
* Returns a String representation of this EventObject.
- *
- * @return a String representation of this EventObject
*/
@Override
public String toString() {
- return getClass().getName() + "[source=" + source + "]";
+ return getClass().getName() + "[source=" + getSource() + "]";
}
}
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/events/lifecycle/ObjectCreatedEvent.java b/api/applib/src/main/java/org/apache/causeway/applib/events/lifecycle/ObjectCreatedEvent.java
index 4825cbeebb..20eee89c97 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/events/lifecycle/ObjectCreatedEvent.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/events/lifecycle/ObjectCreatedEvent.java
@@ -19,7 +19,7 @@
package org.apache.causeway.applib.events.lifecycle;
/**
- * Broadcast when an object (entiy or view model) is first instantiated using
+ * Broadcast when an object (entity or view model) is first instantiated using
* the {@link org.apache.causeway.applib.services.factory.FactoryService}.
*
* @see org.apache.causeway.applib.services.factory.FactoryService#detachedEntity(Class)
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
index cac0ec18bf..a7dafe25b2 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
@@ -27,6 +27,7 @@ import java.util.List;
import org.springframework.lang.Nullable;
import org.apache.causeway.applib.Identifier;
+import org.apache.causeway.applib.events.EventObjectBase;
import org.apache.causeway.applib.events.domain.AbstractDomainEvent;
import org.apache.causeway.applib.events.domain.ActionDomainEvent;
import org.apache.causeway.applib.events.domain.CollectionDomainEvent;
@@ -178,11 +179,7 @@ public class DomainEventHelper {
.filter(paramCount(0))
.getFirst().orElse(null);
if(noArgConstructor!=null) {
-
- final Object event = invokeConstructor(noArgConstructor);
- final ActionDomainEvent<S> ade = uncheckedCast(event);
-
- ade.initSource(source);
+ final ActionDomainEvent<S> ade = EventObjectBase.getInstanceWithSource(type, source).orElseThrow();
ade.setIdentifier(identifier);
ade.setArguments(asList(arguments));
return ade;
@@ -283,17 +280,14 @@ public class DomainEventHelper {
final T oldValue,
final T newValue) throws NoSuchMethodException, SecurityException, IllegalArgumentException {
+
val constructors = _Reflect.getPublicConstructors(type);
val noArgonstructor = constructors
.filter(paramCount(0))
.getFirst().orElse(null);
if(noArgonstructor != null) {
- final Object event = invokeConstructor(noArgonstructor);
- final PropertyDomainEvent<S, T> pde = uncheckedCast(event);
- if(source!=null) {
- pde.initSource(source);
- }
+ final PropertyDomainEvent<S, T> pde = EventObjectBase.getInstanceWithSource(type, source).orElseThrow();
pde.setIdentifier(identifier);
pde.setOldValue(oldValue);
pde.setNewValue(newValue);
@@ -376,10 +370,7 @@ public class DomainEventHelper {
.filter(paramCount(0))
.getFirst().orElse(null);
if(noArgConstructor != null) {
- final Object event = invokeConstructor(noArgConstructor);
- final CollectionDomainEvent<S, T> cde = uncheckedCast(event);
-
- cde.initSource(source);
+ final CollectionDomainEvent<S, T> cde = EventObjectBase.getInstanceWithSource(type, source).orElseThrow();;
cde.setIdentifier(identifier);
return cde;
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacet.java
index 6d94ee1026..3a3104908d 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacet.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacet.java
@@ -18,11 +18,9 @@
*/
package org.apache.causeway.core.metamodel.facets.object.callbacks;
-import org.apache.causeway.applib.exceptions.unrecoverable.DomainModelException;
import org.apache.causeway.core.metamodel.facetapi.Facet;
import org.apache.causeway.core.metamodel.facets.ImperativeFacet;
import org.apache.causeway.core.metamodel.object.ManagedObject;
-import org.apache.causeway.core.metamodel.object.ManagedObjects;
/**
* A {@link Facet} that represents some type of lifecycle callback on the object
@@ -31,24 +29,6 @@ import org.apache.causeway.core.metamodel.object.ManagedObjects;
public interface CallbackFacet
extends ImperativeFacet {
- public void invoke(ManagedObject object);
-
- public static void callCallback(
- final ManagedObject object,
- final Class<? extends CallbackFacet> callbackFacetType) {
-
- ManagedObjects.asSpecified(object)
- .map(ManagedObject::getSpecification)
- .flatMap(spec->spec.lookupFacet(callbackFacetType))
- .ifPresent(callbackFacet->{
- try {
- callbackFacet.invoke(object);
- } catch (final RuntimeException e) {
- throw new DomainModelException(
- "Callback failed. Calling " + callbackFacet + " on " + object, e);
- }
- });
-
- }
+ void invoke(ManagedObject object);
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/CssClassFacetViaDomainObjectLayoutAnnotationUsingCssClassUiEvent.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/CssClassFacetViaDomainObjectLayoutAnnotationUsingCssClassUiEvent.java
index 36abd7e042..080606fcd5 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/CssClassFacetViaDomainObjectLayoutAnnotationUsingCssClassUiEvent.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/CssClassFacetViaDomainObjectLayoutAnnotationUsingCssClassUiEvent.java
@@ -18,13 +18,12 @@
*/
package org.apache.causeway.core.metamodel.facets.object.domainobjectlayout;
-import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import java.util.function.BiConsumer;
import org.apache.causeway.applib.annotation.DomainObjectLayout;
+import org.apache.causeway.applib.events.EventObjectBase;
import org.apache.causeway.applib.events.ui.CssClassUiEvent;
-import org.apache.causeway.applib.exceptions.UnrecoverableException;
import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.members.cssclass.CssClassFacet;
@@ -57,16 +56,16 @@ extends CssClassFacetAbstract {
}
- private final Class<? extends CssClassUiEvent<?>> cssClassUiEventClass;
+ private final Class<? extends CssClassUiEvent<Object>> cssClassUiEventClass;
private final MetamodelEventService metamodelEventService;
private CssClassFacetViaDomainObjectLayoutAnnotationUsingCssClassUiEvent(
final Class<? extends CssClassUiEvent<?>> cssClassUiEventClass,
- final MetamodelEventService metamodelEventService,
- final FacetHolder holder) {
+ final MetamodelEventService metamodelEventService,
+ final FacetHolder holder) {
super(holder, Precedence.EVENT);
- this.cssClassUiEventClass = cssClassUiEventClass;
+ this.cssClassUiEventClass = _Casts.uncheckedCast(cssClassUiEventClass);
this.metamodelEventService = metamodelEventService;
}
@@ -104,16 +103,7 @@ extends CssClassFacetAbstract {
}
private CssClassUiEvent<Object> newCssClassUiEventForPojo(final Object domainObject) {
- try {
- final CssClassUiEvent<Object> cssClassUiEvent = _Casts.uncheckedCast(
- cssClassUiEventClass.getConstructor().newInstance());
- cssClassUiEvent.initSource(domainObject);
- return cssClassUiEvent;
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- throw new UnrecoverableException(ex);
- }
+ return EventObjectBase.getInstanceWithSource(cssClassUiEventClass, domainObject).orElseThrow();
}
@Override
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/IconFacetViaDomainObjectLayoutAnnotationUsingIconUiEvent.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/IconFacetViaDomainObjectLayoutAnnotationUsingIconUiEvent.java
index 20f4b64ef5..2e1e1fba8f 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/IconFacetViaDomainObjectLayoutAnnotationUsingIconUiEvent.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/IconFacetViaDomainObjectLayoutAnnotationUsingIconUiEvent.java
@@ -18,13 +18,12 @@
*/
package org.apache.causeway.core.metamodel.facets.object.domainobjectlayout;
-import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import java.util.function.BiConsumer;
import org.apache.causeway.applib.annotation.DomainObjectLayout;
+import org.apache.causeway.applib.events.EventObjectBase;
import org.apache.causeway.applib.events.ui.IconUiEvent;
-import org.apache.causeway.applib.exceptions.UnrecoverableException;
import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.object.icon.IconFacet;
@@ -56,7 +55,7 @@ extends IconFacetAbstract {
});
}
- private final Class<? extends IconUiEvent<?>> iconUiEventClass;
+ private final Class<? extends IconUiEvent<Object>> iconUiEventClass;
private final MetamodelEventService metamodelEventService;
public IconFacetViaDomainObjectLayoutAnnotationUsingIconUiEvent(
@@ -64,7 +63,7 @@ extends IconFacetAbstract {
final MetamodelEventService metamodelEventService,
final FacetHolder holder) {
super(holder, Precedence.EVENT);
- this.iconUiEventClass = iconUiEventClass;
+ this.iconUiEventClass = _Casts.uncheckedCast(iconUiEventClass);
this.metamodelEventService = metamodelEventService;
}
@@ -97,21 +96,7 @@ extends IconFacetAbstract {
}
private IconUiEvent<Object> newIconUiEvent(final ManagedObject owningAdapter) {
- final Object domainObject = owningAdapter.getPojo();
- return newIconUiEventForPojo(domainObject);
- }
-
- private IconUiEvent<Object> newIconUiEventForPojo(final Object domainObject) {
- try {
- final IconUiEvent<Object> iconUiEvent = _Casts.uncheckedCast(
- iconUiEventClass.getConstructor().newInstance());
- iconUiEvent.initSource(domainObject);
- return iconUiEvent;
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- throw new UnrecoverableException(ex);
- }
+ return EventObjectBase.getInstanceWithSourceSupplier(iconUiEventClass, owningAdapter::getPojo).orElseThrow();
}
@Override
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/LayoutFacetViaDomainObjectLayoutAnnotationUsingLayoutUiEvent.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/LayoutFacetViaDomainObjectLayoutAnnotationUsingLayoutUiEvent.java
index 3d72be8fdf..46ba23e5d9 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/LayoutFacetViaDomainObjectLayoutAnnotationUsingLayoutUiEvent.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/LayoutFacetViaDomainObjectLayoutAnnotationUsingLayoutUiEvent.java
@@ -18,15 +18,13 @@
*/
package org.apache.causeway.core.metamodel.facets.object.domainobjectlayout;
-import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import java.util.function.BiConsumer;
import org.apache.causeway.applib.annotation.DomainObjectLayout;
+import org.apache.causeway.applib.events.EventObjectBase;
import org.apache.causeway.applib.events.ui.LayoutUiEvent;
-import org.apache.causeway.applib.exceptions.UnrecoverableException;
import org.apache.causeway.commons.internal.base._Casts;
-import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.object.layout.LayoutFacet;
import org.apache.causeway.core.metamodel.facets.object.layout.LayoutFacetAbstract;
@@ -58,7 +56,7 @@ implements LayoutFacet {
});
}
- private final Class<? extends LayoutUiEvent<?>> layoutUiEventClass;
+ private final Class<? extends LayoutUiEvent<Object>> layoutUiEventClass;
private final MetamodelEventService metamodelEventService;
private LayoutFacetViaDomainObjectLayoutAnnotationUsingLayoutUiEvent(
@@ -66,7 +64,7 @@ implements LayoutFacet {
final MetamodelEventService metamodelEventService,
final FacetHolder holder) {
super(holder, Precedence.EVENT);
- this.layoutUiEventClass = layoutUiEventClass;
+ this.layoutUiEventClass = _Casts.uncheckedCast(layoutUiEventClass);
this.metamodelEventService = metamodelEventService;
}
@@ -99,22 +97,7 @@ implements LayoutFacet {
}
private LayoutUiEvent<Object> newLayoutUiEvent(final ManagedObject owningAdapter) {
- final Object domainObject = owningAdapter.getPojo();
- return newLayoutUiEvent(domainObject);
- }
-
- private LayoutUiEvent<Object> newLayoutUiEvent(final Object domainObject) {
- try {
- final LayoutUiEvent<Object> layoutUiEvent =
- _Casts.uncheckedCast(
- layoutUiEventClass.getConstructor().newInstance());
- layoutUiEvent.initSource(domainObject);
- return layoutUiEvent;
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- throw new UnrecoverableException(ex);
- }
+ return EventObjectBase.getInstanceWithSourceSupplier(layoutUiEventClass, owningAdapter::getPojo).orElseThrow();
}
@Override
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java
index e42e34e43a..cc84cbe2e6 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobjectlayout/TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent.java
@@ -18,18 +18,16 @@
*/
package org.apache.causeway.core.metamodel.facets.object.domainobjectlayout;
-import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import java.util.function.BiConsumer;
import org.apache.causeway.applib.annotation.DomainObjectLayout;
+import org.apache.causeway.applib.events.EventObjectBase;
import org.apache.causeway.applib.events.ui.TitleUiEvent;
-import org.apache.causeway.applib.exceptions.UnrecoverableException;
import org.apache.causeway.applib.services.i18n.TranslatableString;
import org.apache.causeway.applib.services.i18n.TranslationContext;
import org.apache.causeway.applib.services.i18n.TranslationService;
import org.apache.causeway.commons.internal.base._Casts;
-import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.object.title.TitleFacet;
import org.apache.causeway.core.metamodel.facets.object.title.TitleFacetAbstract;
@@ -73,18 +71,18 @@ extends TitleFacetAbstract {
});
}
- private final Class<? extends TitleUiEvent<?>> titleUiEventClass;
+ private final Class<? extends TitleUiEvent<Object>> titleUiEventClass;
private final TranslationService translationService;
private final TranslationContext translationContext;
private final MetamodelEventService metamodelEventService;
public TitleFacetViaDomainObjectLayoutAnnotationUsingTitleUiEvent(
final Class<? extends TitleUiEvent<?>> titleUiEventClass,
- final TranslationContext translationContext,
- final MetamodelEventService metamodelEventService,
- final FacetHolder holder) {
+ final TranslationContext translationContext,
+ final MetamodelEventService metamodelEventService,
+ final FacetHolder holder) {
super(holder, Precedence.EVENT);
- this.titleUiEventClass = titleUiEventClass;
+ this.titleUiEventClass = _Casts.uncheckedCast(titleUiEventClass);
this.translationService = super.getTranslationService();
this.translationContext = translationContext;
this.metamodelEventService = metamodelEventService;
@@ -139,21 +137,7 @@ extends TitleFacetAbstract {
}
private TitleUiEvent<Object> newTitleUiEvent(final ManagedObject owningAdapter) {
- final Object domainObject = owningAdapter.getPojo();
- return newTitleUiEvent(domainObject);
- }
-
- private TitleUiEvent<Object> newTitleUiEvent(final Object domainObject) {
- try {
- final TitleUiEvent<Object> titleUiEvent = _Casts.uncheckedCast(
- titleUiEventClass.getConstructor().newInstance());
- titleUiEvent.initSource(domainObject);
- return titleUiEvent;
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- throw new UnrecoverableException(ex);
- }
+ return EventObjectBase.getInstanceWithSourceSupplier(titleUiEventClass, owningAdapter::getPojo).orElseThrow();
}
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtil.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtil.java
index 5c3de0e3ec..fd17e5b76f 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtil.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtil.java
@@ -100,6 +100,17 @@ public final class MmEntityUtil {
}
}
+ /**
+ * Side-effect free check for whether given entity is attached.
+ */
+ public static boolean isAttachedEntity(final @Nullable ManagedObject entity) {
+ return entity!=null
+ ? entity.getSpecialization().isEntity()
+ && entity.isBookmarkMemoized()
+ && entity.getEntityState().isAttached()
+ : false;
+ }
+
/**
* @param managedObject
* @return managedObject
diff --git a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/publish/LifecycleCallbackNotifier.java b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/publish/LifecycleCallbackNotifier.java
index 982ecad65d..fe8092077d 100644
--- a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/publish/LifecycleCallbackNotifier.java
+++ b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/publish/LifecycleCallbackNotifier.java
@@ -28,11 +28,12 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.applib.events.EventObjectBase;
import org.apache.causeway.applib.events.lifecycle.AbstractLifecycleEvent;
+import org.apache.causeway.applib.exceptions.unrecoverable.DomainModelException;
import org.apache.causeway.applib.services.eventbus.EventBusService;
import org.apache.causeway.commons.functional.Either;
import org.apache.causeway.commons.internal.base._Casts;
-import org.apache.causeway.commons.internal.factory._InstanceUtil;
import org.apache.causeway.core.metamodel.facets.object.callbacks.CallbackFacet;
import org.apache.causeway.core.metamodel.facets.object.callbacks.CreatedCallbackFacet;
import org.apache.causeway.core.metamodel.facets.object.callbacks.CreatedLifecycleEventFacet;
@@ -55,6 +56,7 @@ import org.apache.causeway.core.runtimeservices.CausewayModuleCoreRuntimeService
import org.apache.causeway.core.transaction.changetracking.events.PostStoreEvent;
import org.apache.causeway.core.transaction.changetracking.events.PreStoreEvent;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;
@@ -70,17 +72,14 @@ import lombok.val;
//@Log4j2
public class LifecycleCallbackNotifier {
- final EventBusService eventBusService;
- //final SpecificationLoader specLoader;
+ final @NonNull EventBusService eventBusService;
public void postCreate(final ManagedObject entity) {
- CallbackFacet.callCallback(entity, CreatedCallbackFacet.class);
- postLifecycleEventIfRequired(entity, CreatedLifecycleEventFacet.class);
+ dispatch(entity, CreatedCallbackFacet.class, CreatedLifecycleEventFacet.class);
}
public void postLoad(final ManagedObject entity) {
- CallbackFacet.callCallback(entity, LoadedCallbackFacet.class);
- postLifecycleEventIfRequired(entity, LoadedLifecycleEventFacet.class);
+ dispatch(entity, LoadedCallbackFacet.class, LoadedLifecycleEventFacet.class);
}
/**
@@ -92,56 +91,62 @@ public class LifecycleCallbackNotifier {
if(pojo==null) {return;}
eventBusService.post(PreStoreEvent.of(pojo));
val entity = eitherWithOrWithoutOid.fold(UnaryOperator.identity(), UnaryOperator.identity());
- CallbackFacet.callCallback(entity, PersistingCallbackFacet.class);
- postLifecycleEventIfRequired(entity, PersistingLifecycleEventFacet.class);
+ dispatch(entity, PersistingCallbackFacet.class, PersistingLifecycleEventFacet.class);
}
public void postPersist(final ManagedObject entity) {
eventBusService.post(PostStoreEvent.of(entity.getPojo()));
- CallbackFacet.callCallback(entity, PersistedCallbackFacet.class);
- postLifecycleEventIfRequired(entity, PersistedLifecycleEventFacet.class);
+ dispatch(entity, PersistedCallbackFacet.class, PersistedLifecycleEventFacet.class);
}
public void preUpdate(final ManagedObject entity) {
eventBusService.post(PreStoreEvent.of(entity.getPojo()));
- CallbackFacet.callCallback(entity, UpdatingCallbackFacet.class);
- postLifecycleEventIfRequired(entity, UpdatingLifecycleEventFacet.class);
+ dispatch(entity, UpdatingCallbackFacet.class, UpdatingLifecycleEventFacet.class);
}
public void postUpdate(final ManagedObject entity) {
- CallbackFacet.callCallback(entity, UpdatedCallbackFacet.class);
- postLifecycleEventIfRequired(entity, UpdatedLifecycleEventFacet.class);
+ dispatch(entity, UpdatedCallbackFacet.class, UpdatedLifecycleEventFacet.class);
}
public void preRemove(final ManagedObject entity) {
- CallbackFacet.callCallback(entity, RemovingCallbackFacet.class);
- postLifecycleEventIfRequired(entity, RemovingLifecycleEventFacet.class);
+ dispatch(entity, RemovingCallbackFacet.class, RemovingLifecycleEventFacet.class);
}
// -- HELPER
- private void postLifecycleEventIfRequired(
- final ManagedObject object,
+ private void dispatch(
+ final ManagedObject entity,
+ final Class<? extends CallbackFacet> callbackFacetType,
final Class<? extends LifecycleEventFacet> lifecycleEventFacetClass) {
- ManagedObjects.asSpecified(object)
+
+ ManagedObjects.asSpecified(entity)
.map(ManagedObject::getSpecification)
.ifPresent(spec->{
+ spec.lookupFacet(callbackFacetType)
+ .ifPresent(callbackFacet->invokeCallback(callbackFacet, entity));
+
spec.lookupFacet(lifecycleEventFacetClass)
.map(LifecycleEventFacet::getEventType)
- .map(_InstanceUtil::createInstance)
- .ifPresent(eventInstance->{
- postEvent(_Casts.uncheckedCast(eventInstance), object.getPojo());
- });
-
+ .ifPresent(eventType->postEvent(_Casts.uncheckedCast(eventType), entity));
});
}
- protected void postEvent(final AbstractLifecycleEvent<Object> event, final Object pojo) {
- if(eventBusService!=null) {
- event.initSource(pojo);
- eventBusService.post(event);
+ protected void invokeCallback(final CallbackFacet callbackFacet, final ManagedObject entity) {
+ try {
+ callbackFacet.invoke(entity);
+ } catch (final RuntimeException e) {
+ throw new DomainModelException(
+ "Callback failed. Calling " + callbackFacet + " on " + entity, e);
}
}
+ protected void postEvent(
+ final Class<? extends AbstractLifecycleEvent<Object>> eventType,
+ final ManagedObject entity) {
+ EventObjectBase
+ .getInstanceWithSourceSupplier(eventType, entity::getPojo)
+ .ifPresent(eventBusService::post);
+ }
+
}