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 2021/07/26 15:35:16 UTC
[isis] branch master updated: ISIS-2573: some housekeeping around
ObjectAssociationContainer and EntityChangeTrackerDefault
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 11bb58c ISIS-2573: some housekeeping around ObjectAssociationContainer and EntityChangeTrackerDefault
11bb58c is described below
commit 11bb58cd2f8752bd56a597177b5d296b796d7c19
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Jul 26 17:35:04 2021 +0200
ISIS-2573: some housekeeping around ObjectAssociationContainer and
EntityChangeTrackerDefault
---
.../spec/feature/ObjectAssociationContainer.java | 22 ++++--
.../runtime/events/TransactionEventEmitter.java | 2 +-
.../changetracking/EntityChangeTrackerDefault.java | 91 ++++++++++++----------
.../publishing/PropertyPublishingTestAbstract.java | 2 +-
.../publishing/jpa/JpaExecutionPublishingTest.java | 2 +
5 files changed, 70 insertions(+), 49 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationContainer.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationContainer.java
index 33ff0f9..679aea5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationContainer.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationContainer.java
@@ -38,22 +38,30 @@ public interface ObjectAssociationContainer {
*/
Optional<ObjectAssociation> getAssociation(String id);
- default ObjectAssociation getAssociationElseFail(String id) {
+ default ObjectAssociation getAssociationElseFail(final String id) {
return getAssociation(id)
.orElseThrow(()->_Exceptions.noSuchElement("id=%s", id));
}
- default OneToOneAssociation getPropertyElseFail(String id) {
+ default Optional<OneToOneAssociation> getProperty(final String id) {
return getAssociation(id)
.filter(ObjectAssociation.Predicates.PROPERTIES)
- .map(OneToOneAssociation.class::cast)
+ .map(OneToOneAssociation.class::cast);
+ }
+
+ default OneToOneAssociation getPropertyElseFail(final String id) {
+ return getProperty(id)
.orElseThrow(()->_Exceptions.noSuchElement("id=%s", id));
}
- default OneToManyAssociation getCollectionElseFail(String id) {
+ default Optional<OneToManyAssociation> getCollection(final String id) {
return getAssociation(id)
.filter(ObjectAssociation.Predicates.COLLECTIONS)
- .map(OneToManyAssociation.class::cast)
+ .map(OneToManyAssociation.class::cast);
+ }
+
+ default OneToManyAssociation getCollectionElseFail(final String id) {
+ return getCollection(id)
.orElseThrow(()->_Exceptions.noSuchElement("id=%s", id));
}
@@ -85,7 +93,7 @@ public interface ObjectAssociationContainer {
* All {@link ObjectAssociation association}s that represent
* {@link OneToOneAssociation properties}.
*/
- default Stream<OneToOneAssociation> streamProperties(MixedIn contributed) {
+ default Stream<OneToOneAssociation> streamProperties(final MixedIn contributed) {
return streamAssociations(contributed)
.filter(ObjectAssociation.Predicates.PROPERTIES)
.map(OneToOneAssociation.class::cast);
@@ -95,7 +103,7 @@ public interface ObjectAssociationContainer {
* All {@link ObjectAssociation association}s that represents
* {@link OneToManyAssociation collections}.
*/
- default Stream<OneToManyAssociation> streamCollections(MixedIn contributed){
+ default Stream<OneToManyAssociation> streamCollections(final MixedIn contributed){
return streamAssociations(contributed)
.filter(ObjectAssociation.Predicates.COLLECTIONS)
.map(OneToManyAssociation.class::cast);
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/events/TransactionEventEmitter.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/events/TransactionEventEmitter.java
index a4bd50c..89e246c 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/events/TransactionEventEmitter.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/events/TransactionEventEmitter.java
@@ -49,7 +49,7 @@ implements TransactionSynchronization, TransactionBoundaryAware {
}
@Override
- public void afterCompletion(int status) {
+ public void afterCompletion(final int status) {
val event = TransactionAfterCompletionEvent.forStatus(status);
eventBusService.post(event);
_Xray.txAfterCompletion(interactionLayerTracker, String.format("tx: afterCompletion (%s)", event.name()));
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerDefault.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerDefault.java
index d94b3b8..db80a68 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerDefault.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerDefault.java
@@ -73,16 +73,14 @@ import org.apache.isis.core.metamodel.facets.object.publish.entitychange.EntityC
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ManagedObjects;
import org.apache.isis.core.metamodel.spec.feature.MixedIn;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.core.transaction.changetracking.events.IsisTransactionPlaceholder;
import org.apache.isis.core.transaction.events.TransactionBeforeCompletionEvent;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
-import lombok.extern.log4j.Log4j2;
import lombok.val;
+import lombok.extern.log4j.Log4j2;
/**
* @since 2.0 {@index}
@@ -122,7 +120,7 @@ implements
private final Provider<InteractionProvider> interactionProviderProvider;
@Inject
- public EntityChangeTrackerDefault(EntityPropertyChangePublisher entityPropertyChangePublisher, EntityChangesPublisher entityChangesPublisher, EventBusService eventBusService, Provider<InteractionProvider> interactionProviderProvider) {
+ public EntityChangeTrackerDefault(final EntityPropertyChangePublisher entityPropertyChangePublisher, final EntityChangesPublisher entityChangesPublisher, final EventBusService eventBusService, final Provider<InteractionProvider> interactionProviderProvider) {
this.entityPropertyChangePublisher = entityPropertyChangePublisher;
this.entityChangesPublisher = entityChangesPublisher;
this.eventBusService = eventBusService;
@@ -154,35 +152,21 @@ implements
}
private void enlistUpdatingInternal(
- final @NonNull ManagedObject adapter,
- String propertyIdIfAny,
- Object preValue) {
- if(!isEntityEnabledForChangePublishing(adapter)) {
+ final @NonNull ManagedObject entity,
+ final String propertyIdIfAny,
+ final Object preValue) {
+ if(!isEntityEnabledForChangePublishing(entity)) {
return;
}
- enlistForChangeKindPublishing(adapter, EntityChangeKind.UPDATE);
+ enlistForChangeKindPublishing(entity, EntityChangeKind.UPDATE);
if(propertyIdIfAny != null) {
- // if we've been provided with the preValue, then just save it
- // in the appropriate PropertyChangeRecord
-
- if(propertyChangeRecordsById.containsKey(propertyIdIfAny)) {
- return;
- }
- adapter.getSpecification().getAssociation(propertyIdIfAny)
- .filter(assoc -> !assoc.isMixedIn())
- .filter(ObjectMember::isOneToOneAssociation)
- .map(OneToOneAssociation.class::cast)
- .filter(property->!property.isNotPersisted())
- .map(property->_PropertyChangeRecord.of(adapter, property))
- .ifPresent(record -> {
- record.setPreValue(preValue);
- propertyChangeRecordsById.put(propertyIdIfAny, record);
- });
-
+ // if we've been provided with the property that changed and its pre-value,
+ // then just save it in the appropriate PropertyChangeRecord
+ enlistForPreAndPostValuePublishing(entity, propertyIdIfAny, preValue);
} else {
- // read from the pojo using the Isis MM.
- enlistForPreAndPostValuePublishing(adapter, _PropertyChangeRecord::updatePreValue);
+ // read all persistent property pre-values from the pojo using the Isis MM.
+ enlistForPreAndPostValuePublishing(entity, _PropertyChangeRecord::updatePreValue);
}
}
@@ -224,7 +208,7 @@ implements
* @apiNote intended to be called during before transaction completion by the framework internally
*/
@EventListener(value = TransactionBeforeCompletionEvent.class) @Order(PriorityPrecedence.LATE)
- public void onTransactionCompleting(TransactionBeforeCompletionEvent event) {
+ public void onTransactionCompleting(final TransactionBeforeCompletionEvent event) {
try {
doPublish();
} finally {
@@ -324,9 +308,36 @@ implements
return previousChangeKind == null;
}
+
+ /**
+ * Variant of {@link #enlistForPreAndPostValuePublishing(ManagedObject, Consumer)},
+ * where we know the changed property and its pre-value in advance (JPA)
+ */
+ private void enlistForPreAndPostValuePublishing(
+ final ManagedObject entity,
+ final String propertyId,
+ final Object preValue) {
+
+ if(propertyChangeRecordsById.containsKey(propertyId)) {
+ return;
+ }
+
+ log.debug("enlist entity's single property change ({}) for publishing {}", propertyId, entity);
+
+ entity.getSpecification().getProperty(propertyId)
+ .filter(property->!property.isMixedIn())
+ .filter(property->!property.isNotPersisted())
+ .map(property->_PropertyChangeRecord.of(entity, property))
+ .ifPresent(record -> {
+ record.setPreValue(preValue);
+ propertyChangeRecordsById.put(record.getPropertyId(), record);
+ });
+
+ }
+
private void enlistForPreAndPostValuePublishing(
final ManagedObject entity,
- final Consumer<_PropertyChangeRecord> fun) {
+ final Consumer<_PropertyChangeRecord> onNewChangeRecord) {
log.debug("enlist entity's property changes for publishing {}", entity);
@@ -335,7 +346,7 @@ implements
.map(property->_PropertyChangeRecord.of(entity, property))
.filter(record->!propertyChangeRecordsById.containsKey(record.getPropertyId())) // already enlisted, so ignore
.forEach(record->{
- fun.accept(record);
+ onNewChangeRecord.accept(record);
propertyChangeRecordsById.put(record.getPropertyId(), record);
});
}
@@ -378,7 +389,7 @@ implements
// -- ENTITY CHANGE TRACKING
@Override
- public void enlistCreated(ManagedObject entity) {
+ public void enlistCreated(final ManagedObject entity) {
_Xray.enlistCreated(entity, interactionProviderProvider);
val hasAlreadyBeenEnlisted = isEnlisted(entity);
enlistCreatedInternal(entity);
@@ -390,7 +401,7 @@ implements
}
@Override
- public void enlistDeleting(ManagedObject entity) {
+ public void enlistDeleting(final ManagedObject entity) {
_Xray.enlistDeleting(entity, interactionProviderProvider);
enlistDeletingInternal(entity);
CallbackFacet.callCallback(entity, RemovingCallbackFacet.class);
@@ -398,12 +409,12 @@ implements
}
@Override
- public void enlistUpdating(ManagedObject entity) {
+ public void enlistUpdating(final ManagedObject entity) {
enlistUpdating(entity, null, null);
}
@Override
- public void enlistUpdating(ManagedObject entity, String propertyIdIfAny, Object preValue) {
+ public void enlistUpdating(final ManagedObject entity, final String propertyIdIfAny, final Object preValue) {
_Xray.enlistUpdating(entity, interactionProviderProvider);
val hasAlreadyBeenEnlisted = isEnlisted(entity);
// we call this come what may;
@@ -418,7 +429,7 @@ implements
}
@Override
- public void recognizeLoaded(ManagedObject entity) {
+ public void recognizeLoaded(final ManagedObject entity) {
_Xray.recognizeLoaded(entity, interactionProviderProvider);
CallbackFacet.callCallback(entity, LoadedCallbackFacet.class);
postLifecycleEventIfRequired(entity, LoadedLifecycleEventFacet.class);
@@ -426,14 +437,14 @@ implements
}
@Override
- public void recognizePersisting(ManagedObject entity) {
+ public void recognizePersisting(final ManagedObject entity) {
_Xray.recognizePersisting(entity, interactionProviderProvider);
CallbackFacet.callCallback(entity, PersistingCallbackFacet.class);
postLifecycleEventIfRequired(entity, PersistingLifecycleEventFacet.class);
}
@Override
- public void recognizeUpdating(ManagedObject entity) {
+ public void recognizeUpdating(final ManagedObject entity) {
_Xray.recognizeUpdating(entity, interactionProviderProvider);
CallbackFacet.callCallback(entity, UpdatedCallbackFacet.class);
postLifecycleEventIfRequired(entity, UpdatedLifecycleEventFacet.class);
@@ -447,8 +458,8 @@ implements
@SuppressWarnings({ "unchecked", "rawtypes" })
private void postLifecycleEventIfRequired(
- ManagedObject adapter,
- Class<? extends LifecycleEventFacet> lifecycleEventFacetClass) {
+ final ManagedObject adapter,
+ final Class<? extends LifecycleEventFacet> lifecycleEventFacetClass) {
val lifecycleEventFacet = adapter.getSpecification().getFacet(lifecycleEventFacetClass);
if(lifecycleEventFacet == null) {
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java
index 65d1189..0924cb2 100644
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java
@@ -49,7 +49,7 @@ implements HasPersistenceStandard {
break;
case POST_COMMIT:
assertHasPropertyChangeEntries(Can.of(
- formatPersistenceStandardSpecificCapitalize("%s Product/name: 'Sample Book' -> 'Book #2'")));
+ formatPersistenceStandardSpecificCapitalize("%s Book/name: 'Sample Book' -> 'Book #2'")));
break;
default:
// if hitting this, the caller is requesting a verification stage, we are providing no case for
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaExecutionPublishingTest.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaExecutionPublishingTest.java
index 0bacee6..92e2ddc 100644
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaExecutionPublishingTest.java
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/jpa/JpaExecutionPublishingTest.java
@@ -43,6 +43,8 @@ import org.apache.isis.testdomain.publishing.conf.Configuration_usingExecutionPu
},
properties = {
"logging.level.org.apache.isis.applib.services.publishing.log.ExecutionLogger=DEBUG",
+ "logging.level.org.apache.isis.persistence.jpa.applib.integration.IsisEntityListener=DEBUG",
+ "logging.level.org.apache.isis.core.transaction.changetracking.EntityChangeTrackerDefault=DEBUG",
"logging.level.org.apache.isis.core.runtimeservices.session.IsisInteractionFactoryDefault=DEBUG",
})
@TestPropertySource({