This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch ISIS-3110 in repository https://gitbox.apache.org/repos/asf/isis.git
commit 5a3af10462e6501b2b94051e76041197ee36784e Author: Dan Haywood <[email protected]> AuthorDate: Wed Aug 3 22:27:38 2022 +0100 ISIS-3110: fixes JDO aud trail integ test --- .../objectlifecycle/PropertyChangeRecord.java | 63 +++++++++------ .../changetracking/EntityChangeTrackerDefault.java | 90 ++++++++++------------ .../jpa/applib/integration/IsisEntityListener.java | 7 +- 3 files changed, 84 insertions(+), 76 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/objectlifecycle/PropertyChangeRecord.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/objectlifecycle/PropertyChangeRecord.java index 5afa259bb5..b93cab05dc 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/objectlifecycle/PropertyChangeRecord.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/objectlifecycle/PropertyChangeRecord.java @@ -38,34 +38,43 @@ import lombok.val; @ToString(of = {"id"}) public final class PropertyChangeRecord { - @Getter - private final PropertyChangeRecordId id; + @Getter private final PropertyChangeRecordId id; + @Getter private PreAndPostValue preAndPostValue; public ManagedObject getEntity() {return id.getEntity();} public OneToOneAssociation getProperty() {return id.getProperty();} public Bookmark getBookmark() {return id.getBookmark();} public String getPropertyId() {return id.getPropertyId();} - @Getter private PreAndPostValue preAndPostValue; + public static PropertyChangeRecord ofNew( + final @NonNull PropertyChangeRecordId pcrId) { + return new PropertyChangeRecord(pcrId) + .withPreValueSetToNew(); + } - public static @NonNull PropertyChangeRecord of( - final @NonNull PropertyChangeRecordId id) { - return new PropertyChangeRecord(id, PreAndPostValue.pre(PropertyValuePlaceholder.NEW)); + public static PropertyChangeRecord ofCurrent( + final @NonNull PropertyChangeRecordId pcrId) { + return new PropertyChangeRecord(pcrId) + .withPreValueSetToCurrent(); } - public static PropertyChangeRecord of( - final @NonNull PropertyChangeRecordId id, - final @NonNull PreAndPostValue preAndPostValue) { - return new PropertyChangeRecord(id, preAndPostValue); + public static PropertyChangeRecord ofCurrent( + final @NonNull PropertyChangeRecordId pcrId, + final Object currentValue) { + return new PropertyChangeRecord(pcrId) + .withPreValueSetTo(currentValue); } - private PropertyChangeRecord( - final @NonNull PropertyChangeRecordId id, - final PreAndPostValue preAndPostValue) { + public static PropertyChangeRecord ofDeleting( + final @NonNull PropertyChangeRecordId id) { + return new PropertyChangeRecord(id) + .withPreValueSetToCurrent() + .withPostValueSetToDeleted(); + } + private PropertyChangeRecord(final @NonNull PropertyChangeRecordId id) { this.id = id; - this.preAndPostValue = preAndPostValue; } public String getLogicalMemberIdentifier() { @@ -74,20 +83,30 @@ public final class PropertyChangeRecord { return target.getLogicalTypeName() + "#" + propertyId; } - public void updatePreValueAsNew() { - preAndPostValue = PreAndPostValue.pre(PropertyValuePlaceholder.NEW); + public PropertyChangeRecord withPreValueSetToNew() { + return withPreValueSetTo(PropertyValuePlaceholder.NEW); + } + + public PropertyChangeRecord withPreValueSetToCurrent() { + return withPreValueSetTo(getPropertyValue()); + } + + public PropertyChangeRecord withPostValueSetToCurrent() { + return withPostValueSetTo(getPropertyValue()); } - public void updatePreValueWithCurrent() { - preAndPostValue = PreAndPostValue.pre(getPropertyValue()); + public PropertyChangeRecord withPostValueSetToDeleted() { + return withPostValueSetTo(PropertyValuePlaceholder.DELETED); } - public void updatePostValueWithCurrent() { - preAndPostValue = preAndPostValue.withPost(getPropertyValue()); + private PropertyChangeRecord withPreValueSetTo(Object preValue) { + this.preAndPostValue = PreAndPostValue.pre(preValue); + return this; } - public void updatePostValueAsDeleted() { - preAndPostValue = preAndPostValue.withPost(PropertyValuePlaceholder.DELETED); + private PropertyChangeRecord withPostValueSetTo(Object postValue) { + this.preAndPostValue = preAndPostValue.withPost(postValue); + return this; } diff --git a/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java index 5a429a9f96..dbf8a49d21 100644 --- a/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java +++ b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java @@ -25,7 +25,6 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.LongAdder; -import java.util.function.Consumer; import javax.annotation.Priority; import javax.inject.Inject; @@ -109,7 +108,6 @@ implements @Getter(AccessLevel.PACKAGE) private final Map<Bookmark, EntityChangeKind> changeKindByEnlistedAdapter = _Maps.newLinkedHashMap(); - private final EntityPropertyChangePublisher entityPropertyChangePublisher; private final EntityChangesPublisher entityChangesPublisher; private final Provider<InteractionProvider> interactionProviderProvider; @@ -130,18 +128,37 @@ implements this.interactionProviderProvider = interactionProviderProvider; } - private boolean isEnlistedWrtChangeKind(final @NonNull ManagedObject adapter) { - return ManagedObjects.bookmark(adapter) - .map(changeKindByEnlistedAdapter::containsKey) - .orElse(false); - } - Set<PropertyChangeRecord> snapshotPropertyChangeRecords() { // this code path has side-effects, it locks the result for this transaction, // such that cannot enlist on top of it return entityPropertyChangeRecordsForPublishing.get(); } + /** + * For any enlisted Object Properties collects those, that are meant for publishing, + * then clears enlisted objects. + */ + private Set<PropertyChangeRecord> capturePostValuesAndDrain() { + + val records = enlistedPropertyChangeRecordsById.values().stream() + // set post values, which have been left empty up to now + .peek(rec -> { + // assuming this check correctly detects deleted entities (JDO) + if(ManagedObjects.EntityUtil.isDetachedOrRemoved(rec.getEntity())) { + rec.withPostValueSetToDeleted(); + } else { + rec.withPostValueSetToCurrent(); + } + }) + .filter(managedProperty->managedProperty.getPreAndPostValue().shouldPublish()) + .collect(_Sets.toUnmodifiable()); + + enlistedPropertyChangeRecordsById.clear(); + + return records; + + } + private boolean isEntityExcludedForChangePublishing(ManagedObject entity) { if(!EntityChangePublishingFacet.isPublishingEnabled(entity.getSpecification())) { @@ -264,30 +281,6 @@ implements return false; } - /** - * For any enlisted Object Properties collects those, that are meant for publishing, - * then clears enlisted objects. - */ - private Set<PropertyChangeRecord> capturePostValuesAndDrain() { - - val records = enlistedPropertyChangeRecordsById.values().stream() - // set post values, which have been left empty up to now - .peek(rec -> { - // assuming this check correctly detects deleted entities (JDO) - if(ManagedObjects.EntityUtil.isDetachedOrRemoved(rec.getEntity())) { - rec.updatePostValueAsDeleted(); - } else { - rec.updatePostValueWithCurrent(); - } - }) - .filter(managedProperty->managedProperty.getPreAndPostValue().shouldPublish()) - .collect(_Sets.toUnmodifiable()); - - enlistedPropertyChangeRecordsById.clear(); - - return records; - - } // side-effect free, used by XRay long countPotentialPropertyChangeRecords() { @@ -308,7 +301,11 @@ implements log.debug("enlist entity's property changes for publishing {}", entity); enlistForChangeKindPublishing(entity, EntityChangeKind.CREATE); - enlistForCreateOrUpdate(entity, PropertyChangeRecord::updatePreValueAsNew); + entity.getSpecification().streamProperties(MixedIn.EXCLUDED) + .filter(property->!EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property)) + .map(property -> PropertyChangeRecordId.of(entity, property)) + .filter(pcrId -> ! enlistedPropertyChangeRecordsById.containsKey(pcrId)) // only if not previously seen + .forEach(pcrId -> enlistedPropertyChangeRecordsById.put(pcrId, PropertyChangeRecord.ofNew(pcrId))); } @Override @@ -331,25 +328,22 @@ implements ormPropertyChangeRecords .stream() .filter(pcr -> !EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(pcr.getProperty())) - .forEach(pcr -> this.enlistedPropertyChangeRecordsById.put(pcr.getId(), pcr)); // if already known, then we don't replace (keep first pre-value we know about) + .filter(pcr -> ! enlistedPropertyChangeRecordsById.containsKey(pcr.getId())) // only if not previously seen + .forEach(pcr -> this.enlistedPropertyChangeRecordsById.put(pcr.getId(), pcr)); } else { // home-grown approach log.debug("enlist entity's property changes for publishing {}", entity); - enlistForCreateOrUpdate(entity, PropertyChangeRecord::updatePreValueWithCurrent); + entity.getSpecification().streamProperties(MixedIn.EXCLUDED) + .filter(property->!EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property)) + .map(property -> PropertyChangeRecordId.of(entity, property)) + .filter(pcrId -> ! enlistedPropertyChangeRecordsById.containsKey(pcrId)) // only if not previously seen + .map(pcrId -> enlistedPropertyChangeRecordsById.put(pcrId, PropertyChangeRecord.ofCurrent(pcrId))) + .filter(Objects::nonNull) // shouldn't happen, just keeping compiler happy + .forEach(PropertyChangeRecord::withPreValueSetToCurrent); } } - private void enlistForCreateOrUpdate(ManagedObject entity, Consumer<PropertyChangeRecord> propertyChangeRecordConsumer) { - entity.getSpecification().streamProperties(MixedIn.EXCLUDED) - .filter(property->!EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property)) - .map(property -> PropertyChangeRecordId.of(entity, property)) - .filter(pcrId -> ! enlistedPropertyChangeRecordsById.containsKey(pcrId)) // only if not previously seen - .map(pcrId -> enlistedPropertyChangeRecordsById.put(pcrId, PropertyChangeRecord.of(pcrId))) - .filter(Objects::nonNull) // shouldn't happen, just keeping compiler happy - .forEach(propertyChangeRecordConsumer); - } - @Override public void enlistDeleting(final ManagedObject entity) { @@ -370,11 +364,7 @@ implements .filter(property -> EntityChangePublishingFacet.isPublishingEnabled(entity.getSpecification())) .filter(property -> !EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property)) .map(property -> PropertyChangeRecordId.of(entity, property)) - .map(pcrId -> enlistedPropertyChangeRecordsById.computeIfAbsent(pcrId, PropertyChangeRecord::of)) - .forEach(pcr -> { - pcr.updatePreValueWithCurrent(); - pcr.updatePostValueAsDeleted(); - }); + .forEach(pcrId -> enlistedPropertyChangeRecordsById.computeIfAbsent(pcrId, id -> PropertyChangeRecord.ofDeleting(id))); } } diff --git a/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/IsisEntityListener.java b/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/IsisEntityListener.java index f49bc6672c..e6cea2121f 100644 --- a/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/IsisEntityListener.java +++ b/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/IsisEntityListener.java @@ -116,10 +116,9 @@ public class IsisEntityListener { return entity .getSpecification() .getProperty(propertyName) - .filter(property->!property.isMixedIn()) - .filter(property->!EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property)) - .map(property->PropertyChangeRecord.of(PropertyChangeRecordId.of(entity, property), - PreAndPostValue.pre(ormChangeRecord.getOldValue()))) + .filter(property -> !property.isMixedIn()) + .filter(property -> !EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property)) + .map(property -> PropertyChangeRecord.ofCurrent(PropertyChangeRecordId.of(entity, property), ormChangeRecord.getOldValue())) .orElse(null); // ignore }) .collect(Can.toCan()); // a Can<T> only collects non-null elements
