You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2022/08/03 21:27:52 UTC

[isis] branch ISIS-3110 updated: ISIS-3110: fixes JDO aud trail integ test

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


The following commit(s) were added to refs/heads/ISIS-3110 by this push:
     new e178e6a927 ISIS-3110: fixes JDO aud trail integ test
e178e6a927 is described below

commit e178e6a927d95da287c964f762fd0f68256c511f
Author: Dan Haywood <da...@haywood-associates.co.uk>
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