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 2021/07/06 12:36:05 UTC

[isis] branch ISIS-2789 updated (299999e -> b940e51)

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a change to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git.


 discard 299999e  ISIS-2789: sketches implementation.
     add 5c8e66a  Bump archunit.version from 0.14.1 to 0.19.0
     add e1886d0  Merge pull request #648 from apache/dependabot/maven/master/archunit.version-0.19.0
     add 9def5fe  ISIS-2775: some MM housekeeping
     add d8d658b  ISIS-2775: Allow mixin actions to be declared on domain services.
     add a636574  ISIS-2785: supposed fix for tooltip shows the base class, rather than concrete
     add 2594e2e  ISIS-2786: add a tab with multiple fieldsets to demo
     add 1a195bf  ISIS-2788: XRay fix: side effect free entity change record count
     add e7e37c0  ISIS-2787: some housekeeping with MM tests
     add c38ff02  ISIS-2787: some housekeeping with MM tests (2)
     add 84bd660  ISIS-2787: convert jmock to mockito test (for learning purposes)
     add e04e7dd  ISIS-2787: more conversions jmock to mockito
     add 8b55e9c  ISIS-2787: some MM test cleanup
     add c778298  ISIS-2787: prepare layout testing infra.
     add 03b53db  ISIS-2787: workaround lombok issues
     add 03f76d6  ISIS-2787: fixes dependency circle with GridReaderUsingJaxb
     add 1e37365  ISIS-2787: better fix for dependency circle with GridReaderUsingJaxb
     add d3fe794  ISIS-2787: another lombok workaround
     add da34190  ISIS-2787: adds menubar testing infra.
     add 0913bc9  ISIS-2787: testing: setup a sample Service that contributes a menu
     add 809d844  ISIS-2790: copies in EmailAddressValidator from wicket
     add 3471df6  ISIS-2790: splits regex across multiple lines
     add f83d292  ISIS-2790: makes more general
     add 7715729  ISIS-2790: adds unit test
     add b6f4ca6  ISIS-2790: updates PasswordResetEmailPanel
     add cc8e6cf  Merge pull request #649 from apache/ISIS-2790
     add 2256813  ISIS-2776: adds guard for null string in regex facet
     add 0b4e9c1  Merge pull request #650 from apache/ISIS-2776
     add 10b2d00  ISIS-2775: excludes mixing in Object_ mixins to domain services
     add 41ee366  Merge pull request #651 from apache/ISIS-2775
     add b179d7a  Bump gradle-tooling-api from 7.1 to 7.1.1
     add e04f259  Merge pull request #653 from apache/dependabot/maven/master/org.gradle-gradle-tooling-api-7.1.1
     add 0e15533  Bump archunit.version from 0.19.0 to 0.20.0
     add 7f3c063  Merge pull request #652 from apache/dependabot/maven/master/archunit.version-0.20.0
     add b074db4  ISIS-2787: housekeeping with tests:
     add 533bf95  ISIS-2787: further fleshing out menu bar tests
     add d4a5884  ISIS-2787: prepare FacetRanking to also serve lower than winning rank
     add 5306000  ISIS-2787: remove the need for canonical facets (use FacetRanking instead)
     add e3658bc  ISIS-2787: create menubars.layout base/fallback model from layout annotations only
     add 4050e14  ISIS-2787: adds ServiceActionNamingPostProcessor (just a stub)
     add 5b89b6a  ISIS-2789: do not destroy InteractionScope(d) objects before tx-boundary events have been processed
     add 29387ad  ISIS-2791: TitleFacetViaMethodsFactory needs to unconditionally remove toString method from action candidates
     add 63631fe  ISIS-2791: fixes test after change in behavior
     new 07a893a  ISIS-2789: sketches implementation.
     new ad4e2fa  ISIS-2789: wip - hacking
     new afd4fe5  ISIS-2789: copies InteractionScope to InteractionScopeHACK prior to rebase
     new 9c44106  ISIS-2789: fixing compile issues in InteractionScopeHACK
     new 1fcf7c6  ISIS-2789: extends EntityChangeTracker to allow JPA (EclipseLink) to provide the 'pre values' already.
     new f175c5d  ISIS-2789: converts Set<ProprttyChangeRecord>s to a map, keyed by propertyId
     new 97fa5c3  ISIS-2789: changes the location of the if for whether PreUpdate whether propertyIdIfAny is provided
     new 2223076  ISIS-2789: for preUpdate, populates the map of _PropertyChangeRecord according to the preValues provided to us.
     new e8a60ee  ISIS-2789: amends _PropertyChangeRecord so picks up changes for JPA deleted
     new 7995ac7  ISIS-2789: enhances CommandLogger, dump out XML as well.
     new b940e51  ISIS-2789: removes my hacked version of InteractionScope as Andi's fix seemed to do the job

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (299999e)
            \
             N -- N -- N   refs/heads/ISIS-2789 (b940e51)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../isis/applib/layout/menubars/MenuBars.java      |  18 ++-
 .../layout/menubars/bootstrap3/BS3MenuBars.java    |  15 +-
 .../applib/services/grid/GridSystemService.java    |   7 -
 .../isis/applib/services/menu/MenuBarsService.java |  18 ++-
 .../isis/applib/services/metamodel/BeanSort.java   |  18 ++-
 .../services/publishing/log/CommandLogger.java     |  16 ++-
 .../reflection/ReflectSampleForTesting.java        |   2 +-
 .../commons/internal/reflection/ReflectTest.java   |  33 +++--
 .../commons/internal/ioc/_ManagedBeanAdapter.java  |  13 ++
 ...ava => _ManagedBeanAdapter_forTestingLazy.java} |  28 ++--
 .../apache/isis/core/config/IsisConfiguration.java |  19 +--
 .../core/interaction/scope/InteractionScope.java   |  30 ++--
 .../scope/InteractionScopeLifecycleHandler.java    |   3 +-
 .../_testing/MetaModelContext_forTesting.java      | 154 ++++++++++++++++++---
 .../_testing/ServiceRegistry_forTesting.java       |  41 +-----
 .../apache/isis/core/metamodel/facetapi/Facet.java |  18 +++
 .../isis/core/metamodel/facetapi/FacetRanking.java |  58 +++++++-
 .../layout/MemberNamedFacetForActionXml.java       |   2 +-
 .../layout/MemberNamedFacetForMenuBarEntry.java}   |  27 ++--
 .../all/described/CanonicalDescribedFacet.java     |  37 -----
 .../described/CanonicalDescribedFacetAbstract.java |  47 -------
 .../facets/all/described/MemberDescribedFacet.java |   5 +
 .../imperative/HasImperativeTextFacetAbstract.java |   4 +-
 .../facets/all/named/CanonicalNamedFacet.java      |  38 -----
 .../all/named/CanonicalNamedFacetAbstract.java     |  42 ------
 .../facets/all/named/MemberNamedFacet.java         |   5 +
 ...escribedFacetForCollectionLayoutAnnotation.java |  50 -------
 .../CanonicalDescribedFacetForCollectionXml.java   |  51 -------
 ...calNamedFacetForCollectionLayoutAnnotation.java |  50 -------
 .../layout/CollectionLayoutFacetFactory.java       |   8 --
 .../MemberDescribedFacetForCollectionXml.java      |   2 +-
 .../layout/MemberNamedFacetForCollectionXml.java   |   2 +-
 ...ctFacetForRecreatableDomainObjectInterface.java |   3 +-
 .../title/methods/TitleFacetViaMethodsFactory.java |  57 +++++---
 .../objectvalue/regex/RegExFacetAbstract.java      |   3 +
 ...lDescribedFacetForPropertyLayoutAnnotation.java |  49 -------
 .../CanonicalDescribedFacetForPropertyXml.java     |  51 -------
 ...nicalNamedFacetForPropertyLayoutAnnotation.java |  52 -------
 .../CanonicalNamedFacetForPropertyXml.java         |  50 -------
 .../MemberDescribedFacetForPropertyXml.java        |   2 +-
 .../MemberNamedFacetForPropertyXml.java            |   2 +-
 .../propertylayout/PropertyLayoutFacetFactory.java |   8 --
 ....java => ServiceActionNamingPostProcessor.java} |  30 ++--
 .../all/i18n/TranslationPostProcessor.java         |  10 +-
 .../dflt/ProgrammingModelFacetsJava8.java          |   7 +-
 .../services/grid/GridLoaderServiceDefault.java    |   8 +-
 .../services/grid/GridReaderUsingJaxb.java         |  36 +++--
 .../services/grid/GridServiceDefault.java          |  39 +++---
 .../services/grid/GridSystemServiceAbstract.java   |  55 ++------
 .../bootstrap3/GridSystemServiceBootstrap.java     |  38 ++++-
 .../services/layout/LayoutServiceDefault.java      |  29 ++--
 .../specloader/specimpl/ObjectActionDefault.java   |   4 +-
 .../specloader/specimpl/ObjectActionMixedIn.java   |   3 +-
 .../specimpl/ObjectAssociationAbstract.java        |  29 ++--
 .../specloader/specimpl/ObjectMemberAbstract.java  |  63 +++------
 .../specloader/specimpl/ObjectMemberContainer.java |   8 +-
 .../specimpl/ObjectSpecificationAbstract.java      |  40 ++----
 .../{Factories.java => _MixedInMemberFactory.java} |  17 ++-
 .../isis/core/metamodel/MetaModelTestAbstract.java |  70 ++++++++++
 .../facets/AbstractFacetFactoryJUnit4TestCase.java |  54 ++------
 .../action/ActionAnnotationFacetFactoryTest.java   |   3 -
 .../collections/JavaCollectionFacetTest.java       |  67 +++------
 .../title/TitleFacetViaMethodsFactoryTest.java     |   3 +-
 .../TitleAnnotationFacetFactoryTest.java           |  23 +--
 .../facets/object/mixin/MixinIntendedAs.java       |  26 +---
 .../NavigableParentAnnotationFacetFactoryTest.java |  29 ----
 .../facets/param/name/ParameterNameFacetTest.java  |   4 -
 .../ParameterAnnotationFacetFactoryTest.java       |  12 +-
 .../PropertyAnnotationFacetFactoryTest.java        |  12 +-
 .../objects/ObjectActionLayoutXmlDefaultTest.java  |  72 ++++------
 .../objects/OneToManyAssociationDefaultTest.java   | 120 ++++------------
 .../isis/core/metamodel/services/grid/Bar.java}    |  20 ++-
 .../grid/{Foo3.layout.xml => Bar.layout.xml}       |   0
 .../services/grid/GridInferringRoundtripTest.java  |  60 ++++++++
 ...GridLoaderServiceDefault_resourceNameTest.java} |   8 +-
 ...{BS3GridTest.java => GridXmlRoundtripTest.java} |  28 ++--
 .../services/title/TitleServiceDefaultTest.java    |  30 +---
 .../SpecificationLoaderTestAbstract.java           |  85 +-----------
 core/pom.xml                                       |   2 +-
 .../menubars/MenuBarsLoaderServiceDefault.java     |  26 ++--
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    |  87 +++++++-----
 .../session/InteractionServiceDefault.java         |   3 +-
 .../RuntimeServicesTestAbstract.java               | 119 ++++++++++++++++
 .../runtimeservices/menubars/bootstrap3/Bar.java}  |  20 ++-
 .../bootstrap3/MenuBarsServiceBS3Test.java         | 137 ++++++++++++++++++
 .../changetracking/EntityChangeTrackerDefault.java | 122 +++++++++++-----
 .../EntityChangeTrackerWithPreValue.java           |  43 ++++++
 .../changetracking/_ChangingEntitiesFactory.java   |   4 +-
 .../changetracking/_PropertyChangeRecord.java      |   4 +-
 .../core/transaction/changetracking/_Xray.java     |   4 +-
 .../demoapp/dom/featured/layout/tabs/TabDemo.java  |  13 +-
 .../dom/featured/layout/tabs/TabDemo.layout.xml    |  16 ++-
 extensions/pom.xml                                 |   5 +
 .../ui/components/markup/MarkupFieldFactory.java   |   3 +-
 .../SpecificationLoaderTestAbstract.java           |  88 +-----------
 .../jpa/applib/integration/IsisEntityListener.java |  29 +++-
 .../DomainModelTest_usingGoodDomain.java           |  27 ++++
 .../model/good/ProperServiceWithMixin.java         |  30 ++--
 tooling/pom.xml                                    |   2 +-
 .../resources/MenuBarsResourceServerside.java      |  12 +-
 .../entity/icontitle/EntityIconAndTitlePanel.java  |  27 +++-
 .../password_reset/EmailAddressValidator.java      |  29 ++++
 .../password_reset/PasswordResetEmailPanel.java    |   1 -
 .../password_reset/EmailAddressValidator_Test.java |  59 ++++++++
 104 files changed, 1576 insertions(+), 1616 deletions(-)
 copy {core/runtimeservices/src/test/java/org/apache/isis/core/metamodel => api/applib/src/test/java/org/apache/isis/applib}/commons/internal/reflection/ReflectSampleForTesting.java (94%)
 rename {core/runtimeservices/src/test/java/org/apache/isis/core/metamodel => api/applib/src/test/java/org/apache/isis/applib}/commons/internal/reflection/ReflectTest.java (83%)
 copy commons/src/main/java/org/apache/isis/commons/internal/ioc/{_ManagedBeanAdapter.java => _ManagedBeanAdapter_forTestingLazy.java} (63%)
 rename core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/{collections/layout/CanonicalNamedFacetForCollectionXml.java => actions/layout/MemberNamedFacetForMenuBarEntry.java} (58%)
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/CanonicalDescribedFacet.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/described/CanonicalDescribedFacetAbstract.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/CanonicalNamedFacet.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/CanonicalNamedFacetAbstract.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CanonicalDescribedFacetForCollectionLayoutAnnotation.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CanonicalDescribedFacetForCollectionXml.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CanonicalNamedFacetForCollectionLayoutAnnotation.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/CanonicalDescribedFacetForPropertyLayoutAnnotation.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/CanonicalDescribedFacetForPropertyXml.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/CanonicalNamedFacetForPropertyLayoutAnnotation.java
 delete mode 100644 core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/propertylayout/CanonicalNamedFacetForPropertyXml.java
 rename core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/all/i18n/{InferCanonicalNamingPostProcessor.java => ServiceActionNamingPostProcessor.java} (69%)
 rename core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/{Factories.java => _MixedInMemberFactory.java} (78%)
 create mode 100644 core/metamodel/src/test/java/org/apache/isis/core/metamodel/MetaModelTestAbstract.java
 copy core/metamodel/src/{main/java/org/apache/isis/core/metamodel/facets/all/named/CanonicalNamedFacetInferredFromAssociationNaturalName.java => test/java/org/apache/isis/core/metamodel/services/grid/Bar.java} (65%)
 copy core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/{Foo3.layout.xml => Bar.layout.xml} (100%)
 create mode 100644 core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/GridInferringRoundtripTest.java
 rename core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/{GridLoaderServiceDefault_resourceNameFor_Test.java => GridLoaderServiceDefault_resourceNameTest.java} (97%)
 rename core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/{BS3GridTest.java => GridXmlRoundtripTest.java} (89%)
 create mode 100644 core/runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/RuntimeServicesTestAbstract.java
 rename core/{metamodel/src/main/java/org/apache/isis/core/metamodel/facets/all/named/CanonicalNamedFacetInferredFromAssociationNaturalName.java => runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/Bar.java} (65%)
 create mode 100644 core/runtimeservices/src/test/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3Test.java
 create mode 100644 core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerWithPreValue.java
 rename core/runtimeservices/src/test/java/org/apache/isis/core/metamodel/commons/internal/reflection/ReflectSampleForTesting.java => regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ProperServiceWithMixin.java (58%)
 create mode 100644 viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/accmngt/password_reset/EmailAddressValidator.java
 create mode 100644 viewers/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/pages/accmngt/password_reset/EmailAddressValidator_Test.java

[isis] 07/11: ISIS-2789: changes the location of the if for whether PreUpdate whether propertyIdIfAny is provided

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 97fa5c3172d09ac2f94ade5d13a3a735d5ab3268
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:17:30 2021 +0100

    ISIS-2789: changes the location of the if for whether PreUpdate whether propertyIdIfAny is provided
    
    ... because our algorithm at the moment is incorrect; it will only capture one pre value and leave the rest as null.  Instead, we need to lazily populate.  That's coming next.
---
 .../changetracking/EntityChangeTrackerDefault.java | 29 +++++++++++-----------
 1 file changed, 15 insertions(+), 14 deletions(-)

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 9fb8e9c..9eaa9ba 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
@@ -103,7 +103,7 @@ implements
     /**
      * Contains initial change records having set the pre-values of every property of every object that was enlisted.
      */
-    private final Map<String,_PropertyChangeRecord> entityPropertyChangeRecords = _Maps.newLinkedHashMap();
+    private final Map<String,_PropertyChangeRecord> propertyChangeRecordsById = _Maps.newLinkedHashMap();
 
     /**
      * Contains pre- and post- values of every property of every object that actually changed. A lazy snapshot,
@@ -160,18 +160,19 @@ implements
             return;
         }
         enlistForChangeKindPublishing(adapter, EntityChangeKind.UPDATE);
-        enlistForPreAndPostValuePublishing(adapter, propertyChangeRecord -> {
-            if(propertyIdIfAny != null) {
+
+        if(propertyIdIfAny != null) {
+            enlistForPreAndPostValuePublishing(adapter, propertyChangeRecord -> {
                 // if we've been provided with the preValue, then just save it
                 // in the appropriate PropertyChangeRecord
                 if(Objects.equals(propertyChangeRecord.getPropertyId(), propertyIdIfAny)) {
                     propertyChangeRecord.setPreValue(preValue);
                 }
-            } else {
-                // read from the pojo using the Isis MM.
-                propertyChangeRecord.updatePreValue();
-            }
-        });
+            });
+        } else {
+            // read from the pojo using the Isis MM.
+            enlistForPreAndPostValuePublishing(adapter, _PropertyChangeRecord::updatePreValue);
+        }
     }
 
     private void enlistDeletingInternal(final @NonNull ManagedObject adapter) {
@@ -230,7 +231,7 @@ implements
 
     private void postPublishing() {
         log.debug("purging entity change records");
-        entityPropertyChangeRecords.clear();
+        propertyChangeRecordsById.clear();
         changeKindByEnlistedAdapter.clear();
         entityPropertyChangeRecordsForPublishing.clear();
         entityChangeEventCount.reset();
@@ -321,10 +322,10 @@ implements
         entity.getSpecification().streamProperties(MixedIn.EXCLUDED)
         .filter(property->!property.isNotPersisted())
         .map(property->_PropertyChangeRecord.of(entity, property))
-        .filter(record->!entityPropertyChangeRecords.containsKey(record.getPropertyId())) // already enlisted, so ignore
+        .filter(record->!propertyChangeRecordsById.containsKey(record.getPropertyId())) // already enlisted, so ignore
         .forEach(record->{
             fun.accept(record);
-            entityPropertyChangeRecords.put(record.getPropertyId(), record);
+            propertyChangeRecordsById.put(record.getPropertyId(), record);
         });
     }
 
@@ -334,13 +335,13 @@ implements
      */
     private Set<_PropertyChangeRecord> capturePostValuesAndDrain() {
 
-        val records = entityPropertyChangeRecords.values().stream()
+        val records = propertyChangeRecordsById.values().stream()
                 // set post values, which have been left empty up to now
                 .peek(_PropertyChangeRecord::updatePostValue)
                 .filter(managedProperty->managedProperty.getPreAndPostValue().shouldPublish())
                 .collect(_Sets.toUnmodifiable());
 
-        entityPropertyChangeRecords.clear();
+        propertyChangeRecordsById.clear();
 
         return records;
 
@@ -348,7 +349,7 @@ implements
 
     // side-effect free, used by XRay
     long countPotentialPropertyChangeRecords() {
-        return entityPropertyChangeRecords.size();
+        return propertyChangeRecordsById.size();
     }
 
     // -- METRICS SERVICE

[isis] 05/11: ISIS-2789: extends EntityChangeTracker to allow JPA (EclipseLink) to provide the 'pre values' already.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 1fcf7c6f927739c2e44fd4e27201f515a52a9087
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:07:34 2021 +0100

    ISIS-2789: extends EntityChangeTracker to allow JPA (EclipseLink) to provide the 'pre values' already.
    
    This is more efficient, but is also necessary as the pojo itself that we have will already have been updated.
---
 .../changetracking/EntityChangeTrackerDefault.java | 29 ++++++++++++---
 .../EntityChangeTrackerWithPreValue.java           | 43 ++++++++++++++++++++++
 .../jpa/applib/integration/IsisEntityListener.java | 33 +++++++++++++----
 3 files changed, 92 insertions(+), 13 deletions(-)

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 102f662..58bba51 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
@@ -19,6 +19,7 @@
 package org.apache.isis.core.transaction.changetracking;
 
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -94,7 +95,7 @@ import lombok.extern.log4j.Log4j2;
 public class EntityChangeTrackerDefault
 implements
     MetricsService,
-    EntityChangeTracker,
+        EntityChangeTrackerWithPreValue,
     HasEnlistedEntityPropertyChanges,
     HasEnlistedEntityChanges {
 
@@ -151,12 +152,26 @@ implements
         enlistForPreAndPostValuePublishing(adapter, record->record.setPreValue(IsisTransactionPlaceholder.NEW));
     }
 
-    private void enlistUpdatingInternal(final @NonNull ManagedObject adapter) {
+    private void enlistUpdatingInternal(
+            final @NonNull ManagedObject adapter,
+            String propertyIdIfAny,
+            Object preValue) {
         if(!isEntityEnabledForChangePublishing(adapter)) {
             return;
         }
         enlistForChangeKindPublishing(adapter, EntityChangeKind.UPDATE);
-        enlistForPreAndPostValuePublishing(adapter, _PropertyChangeRecord::updatePreValue);
+        enlistForPreAndPostValuePublishing(adapter, propertyChangeRecord -> {
+            if(propertyIdIfAny != null) {
+                // if we've been provided with the preValue, then just save it
+                // in the appropriate PropertyChangeRecord
+                if(Objects.equals(propertyChangeRecord.getPropertyId(), propertyIdIfAny)) {
+                    propertyChangeRecord.setPreValue(preValue);
+                }
+            } else {
+                // read from the pojo using the Isis MM.
+                propertyChangeRecord.updatePreValue();
+            }
+        });
     }
 
     private void enlistDeletingInternal(final @NonNull ManagedObject adapter) {
@@ -372,11 +387,16 @@ implements
 
     @Override
     public void enlistUpdating(ManagedObject entity) {
+        enlistUpdating(entity, null, null);
+    }
+
+    @Override
+    public void enlistUpdating(ManagedObject entity, String propertyIdIfAny, Object preValue) {
         _Xray.enlistUpdating(entity, interactionProviderProvider);
         val hasAlreadyBeenEnlisted = isEnlisted(entity);
         // we call this come what may;
         // additional properties may now have been changed, and the changeKind for publishing might also be modified
-        enlistUpdatingInternal(entity);
+        enlistUpdatingInternal(entity, propertyIdIfAny, preValue);
 
         if(!hasAlreadyBeenEnlisted) {
             // prevent an infinite loop... don't call the 'updating()' callback on this object if we have already done so
@@ -437,5 +457,4 @@ implements
     }
 
 
-
 }
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerWithPreValue.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerWithPreValue.java
new file mode 100644
index 0000000..9efdbca
--- /dev/null
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/EntityChangeTrackerWithPreValue.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.transaction.changetracking;
+
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+
+/**
+ * @since 2 {@index}
+ */
+public interface EntityChangeTrackerWithPreValue extends EntityChangeTracker {
+
+    /**
+     * An override of {@link EntityChangeTracker#enlistUpdating(ManagedObject)}
+     * where the caller already knows the old value (and so the
+     * {@link EntityChangeTracker} does not need to capture the old value itself.
+     *
+     * <p>
+     *     Introduced for JPA (EclipseLink implementation).
+     * </p>
+     *
+     * @param entity - being enlisted
+     * @param propertyIdIfAny - the entity property id (its simple name); if non-null, indicates that the pre value is known
+     * @param preValue - the pre-value (could be null); only relevant if propertyNameIfAny is provided (non-null).
+     */
+    void enlistUpdating(ManagedObject entity, String propertyIdIfAny, Object preValue);
+}
+
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 6d3dfe6..2b4c660 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
@@ -19,6 +19,7 @@
 package org.apache.isis.persistence.jpa.applib.integration;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 import javax.persistence.PostLoad;
 import javax.persistence.PostPersist;
 import javax.persistence.PostRemove;
@@ -27,9 +28,13 @@ import javax.persistence.PrePersist;
 import javax.persistence.PreRemove;
 import javax.persistence.PreUpdate;
 
+import org.eclipse.persistence.sessions.UnitOfWork;
+
 import org.apache.isis.applib.services.inject.ServiceInjector;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.transaction.changetracking.EntityChangeTracker;
+import org.apache.isis.core.transaction.changetracking.EntityChangeTrackerWithPreValue;
+import org.apache.isis.persistence.jpa.applib.services.JpaSupportService;
 
 import lombok.extern.log4j.Log4j2;
 import lombok.val;
@@ -54,13 +59,8 @@ public class IsisEntityListener {
 
     // not managed by Spring (directly)
     @Inject private ServiceInjector serviceInjector;
-    private EntityChangeTracker entityChangeTracker;
-
-    @Inject
-    public void setEntityChangeTracker(EntityChangeTracker entityChangeTracker) {
-        this.entityChangeTracker = entityChangeTracker;
-    }
-
+    @Inject private Provider<EntityChangeTrackerWithPreValue> entityChangeTrackerProvider;
+    @Inject private Provider<JpaSupportService> jpaSupportServiceProvider;
     @Inject private ObjectManager objectManager;
 
 
@@ -69,6 +69,7 @@ public class IsisEntityListener {
         log.debug("onPrePersist: {}", entityPojo);
         serviceInjector.injectServicesInto(entityPojo);
         val entity = objectManager.adapt(entityPojo);
+        val entityChangeTracker = entityChangeTrackerProvider.get();
         entityChangeTracker.recognizePersisting(entity);
     }
 
@@ -77,7 +78,19 @@ public class IsisEntityListener {
         log.debug("onPreUpdate: {}", entityPojo);
         serviceInjector.injectServicesInto(entityPojo);
         val entity = objectManager.adapt(entityPojo);
-        entityChangeTracker.enlistUpdating(entity);
+        val entityChangeTracker = entityChangeTrackerProvider.get();
+        val entityManagerResult = jpaSupportServiceProvider.get().getEntityManager(entityPojo.getClass());
+        entityManagerResult.getValue().ifPresent(em -> {  // https://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_access_what_changed_in_an_object_or_transaction.3F
+            val unwrap = em.unwrap(UnitOfWork.class);
+            val changes = unwrap.getCurrentChanges();
+            val objectChanges = changes.getObjectChangeSetForClone(entityPojo);
+            val changeRecords = objectChanges.getChanges();
+            changeRecords.forEach(changeRecord -> {
+                val propertyName = changeRecord.getAttribute();
+                val oldValue = changeRecord.getOldValue();
+                entityChangeTracker.enlistUpdating(entity, propertyName, oldValue);
+            });
+        });
     }
 
     @PreRemove
@@ -85,6 +98,7 @@ public class IsisEntityListener {
         log.debug("onAnyRemove: {}", entityPojo);
         serviceInjector.injectServicesInto(entityPojo);
         val entity = objectManager.adapt(entityPojo);
+        val entityChangeTracker = entityChangeTrackerProvider.get();
         entityChangeTracker.enlistDeleting(entity);
     }
 
@@ -92,6 +106,7 @@ public class IsisEntityListener {
     private void onPostPersist(Object entityPojo) {
         log.debug("onPostPersist: {}", entityPojo);
         val entity = objectManager.adapt(entityPojo);
+        val entityChangeTracker = entityChangeTrackerProvider.get();
         entityChangeTracker.enlistCreated(entity);
     }
 
@@ -99,6 +114,7 @@ public class IsisEntityListener {
     private void onPostUpdate(Object entityPojo) {
         log.debug("onPostUpdate: {}", entityPojo);
         val entity = objectManager.adapt(entityPojo);
+        val entityChangeTracker = entityChangeTrackerProvider.get();
         entityChangeTracker.recognizeUpdating(entity);
     }
 
@@ -112,6 +128,7 @@ public class IsisEntityListener {
         log.debug("onPostLoad: {}", entityPojo);
         serviceInjector.injectServicesInto(entityPojo);
         val entity = objectManager.adapt(entityPojo);
+        val entityChangeTracker = entityChangeTrackerProvider.get();
         entityChangeTracker.recognizeLoaded(entity);
     }
 

[isis] 08/11: ISIS-2789: for preUpdate, populates the map of _PropertyChangeRecord according to the preValues provided to us.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 22230768706f9aa1a72a8e14813480141b2f123d
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:25:57 2021 +0100

    ISIS-2789: for preUpdate, populates the map of _PropertyChangeRecord according to the preValues provided to us.
---
 .../changetracking/EntityChangeTrackerDefault.java | 29 +++++++++++++++-------
 1 file changed, 20 insertions(+), 9 deletions(-)

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 9eaa9ba..d94b3b8 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
@@ -19,7 +19,6 @@
 package org.apache.isis.core.transaction.changetracking;
 
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -74,14 +73,16 @@ 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.val;
 import lombok.extern.log4j.Log4j2;
+import lombok.val;
 
 /**
  * @since 2.0 {@index}
@@ -162,13 +163,23 @@ implements
         enlistForChangeKindPublishing(adapter, EntityChangeKind.UPDATE);
 
         if(propertyIdIfAny != null) {
-            enlistForPreAndPostValuePublishing(adapter, propertyChangeRecord -> {
-                // if we've been provided with the preValue, then just save it
-                // in the appropriate PropertyChangeRecord
-                if(Objects.equals(propertyChangeRecord.getPropertyId(), propertyIdIfAny)) {
-                    propertyChangeRecord.setPreValue(preValue);
-                }
-            });
+            // 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);
+                });
+
         } else {
             // read from the pojo using the Isis MM.
             enlistForPreAndPostValuePublishing(adapter, _PropertyChangeRecord::updatePreValue);

[isis] 04/11: ISIS-2789: fixing compile issues in InteractionScopeHACK

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 9c44106ed648e21667263a48493178a653edd522
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 08:34:25 2021 +0100

    ISIS-2789: fixing compile issues in InteractionScopeHACK
---
 .../isis/core/interaction/scope/InteractionScopeHACK.java | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
index 4b5d39e..3a3c590 100644
--- a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
+++ b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
@@ -156,7 +156,7 @@ class InteractionScopeHACK implements Scope, InteractionScopeLifecycleHandler {
     }
 
     @Override
-    public void onTopLevelInteractionClosing() {
+    public void onTopLevelInteractionPreDestroy() {
         ensureInteractionLayerTrackerInjected();
         iInteractionLayerTracker.currentInteraction()
                 .ifPresent(interaction -> {
@@ -167,6 +167,19 @@ class InteractionScopeHACK implements Scope, InteractionScopeLifecycleHandler {
                     val scopedObjectValues = scopedObjects.values();
                     scopedObjectValues.forEach(ScopedObject::preDestroy);
                     scopedObjects.clear();
+                });
+    }
+
+    @Override
+    public void onTopLevelInteractionClosed() {
+        ensureInteractionLayerTrackerInjected();
+        iInteractionLayerTracker.currentInteraction()
+                .ifPresent(interaction -> {
+                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
+                    if (scopedObjects == null) {
+                        return;
+                    }
+                    scopedObjects.clear();
                     interaction.removeAttribute(ScopedObjects.class);
                 });
     }

[isis] 01/11: ISIS-2789: sketches implementation.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 07a893ac69177e182954530e42374ffa9b932e56
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Fri Jul 2 15:36:48 2021 +0100

    ISIS-2789: sketches implementation.
    
    However, I find that the EntityChangeTrackerDefault that is queried for snapshots at end of interaction is a different instance to the one in which changes are enlisted (for an initial persist).  Unsurprisingly, we get no entity property changes published.  Is there an issue with @InteractionScope (InteractionScopeLifecycleHandler)
---
 .../core/interaction/scope/InteractionScope.java   |   4 +-
 .../changetracking/EntityChangeTrackerDefault.java |   3 +-
 persistence/jpa/applib/pom.xml                     |  12 ++-
 .../jpa/applib/integration/IsisEntityListener.java | 112 +++++++++++++++++++++
 .../JpaEntityInjectionPointResolver.java           |  48 +--------
 .../util/interaction/InteractionBoundaryProbe.java |   6 +-
 6 files changed, 132 insertions(+), 53 deletions(-)

diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScope.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScope.java
index 808562c..3eed6fa 100644
--- a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScope.java
+++ b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScope.java
@@ -49,7 +49,7 @@ class InteractionScope implements Scope, InteractionScopeLifecycleHandler {
         Object instance;
         Runnable destructionCallback;
         void preDestroy() {
-            log.debug("destroy isis-session scoped {}", name);
+            log.debug("destroy isis-interaction scoped {}", name);
             if(destructionCallback!=null) {
                 destructionCallback.run();
             }
@@ -81,7 +81,7 @@ class InteractionScope implements Scope, InteractionScopeLifecycleHandler {
         val newScopedObject = ScopedObject.of(name);
         scopedObjects.get().put(name, newScopedObject); // just set a stub with a name only
 
-        log.debug("create new isis-session scoped {}", name);
+        log.debug("create new isis-interaction scoped {}", name);
         newScopedObject.setInstance(objectFactory.getObject()); // triggers call to registerDestructionCallback
 
         return newScopedObject.getInstance();
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 208f847..ce2f01a 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
@@ -32,6 +32,7 @@ import javax.inject.Provider;
 
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.EntityChangeKind;
@@ -174,7 +175,7 @@ implements
      * TRANSACTION END BOUNDARY
      * @apiNote intended to be called during before transaction completion by the framework internally
      */
-    @EventListener(value = TransactionBeforeCompletionEvent.class)
+    @EventListener(value = TransactionBeforeCompletionEvent.class) @Order(PriorityPrecedence.LATE)
     public void onTransactionCompleting(TransactionBeforeCompletionEvent event) {
         try {
             doPublish();
diff --git a/persistence/jpa/applib/pom.xml b/persistence/jpa/applib/pom.xml
index a07b8f0..f9be8c0 100644
--- a/persistence/jpa/applib/pom.xml
+++ b/persistence/jpa/applib/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-	license agreements. See the NOTICE file distributed with this work for additional 
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
+	license agreements. See the NOTICE file distributed with this work for additional
 	information regarding copyright ownership. The ASF licenses this file to 
 	you under the Apache License, Version 2.0 (the "License"); you may not use 
 	this file except in compliance with the License. You may obtain a copy of 
@@ -77,7 +77,13 @@
 			<artifactId>isis-commons</artifactId>
 		</dependency>
 
-		<!-- TODO JPA API (providing compile dependency) -->
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-transaction</artifactId>
+			<scope>provided</scope>
+        </dependency>
+
+        <!-- TODO JPA API (providing compile dependency) -->
 
 
 	</dependencies>
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
new file mode 100644
index 0000000..a9b0af2
--- /dev/null
+++ b/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/IsisEntityListener.java
@@ -0,0 +1,112 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.persistence.jpa.applib.integration;
+
+import javax.inject.Inject;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+
+import org.apache.isis.applib.services.inject.ServiceInjector;
+import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
+import org.apache.isis.core.transaction.changetracking.EntityChangeTracker;
+
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+/**
+ * EntityListener class for listing with the {@link javax.persistence.EntityListeners} annotation, to
+ * support injection point resolving for entities, and to notify {@link EntityChangeTracker} of changes.
+ *
+ * <p>
+ * Instances of this class are not managed by Spring, but by the persistence layer.
+ * </p>
+ *
+ * <p>
+ * The particular persistence layer implementation in use needs to be configured,
+ * with a BeanManager, that is able to resolve injection points for this EntityListener.
+ * </p>
+ *
+ * @since 2.0 {@index}
+ */
+@Log4j2
+public class IsisEntityListener {
+
+    // not managed by Spring (directly)
+    @Inject private ServiceInjector serviceInjector;
+    @Inject private EntityChangeTracker entityChangeTracker;
+    @Inject private ObjectManager objectManager;
+
+
+    @PrePersist
+    private void onPrePersist(Object entityPojo) {
+        log.debug("onPrePersist: {}", entityPojo);
+        serviceInjector.injectServicesInto(entityPojo);
+        val entity = objectManager.adapt(entityPojo);
+        entityChangeTracker.recognizePersisting(entity);
+    }
+
+    @PreUpdate
+    private void onPreUpdate(Object entityPojo) {
+        log.debug("onPreUpdate: {}", entityPojo);
+        serviceInjector.injectServicesInto(entityPojo);
+        val entity = objectManager.adapt(entityPojo);
+        entityChangeTracker.enlistUpdating(entity);
+    }
+
+    @PreRemove
+    private void onPreRemove(Object entityPojo) {
+        log.debug("onAnyRemove: {}", entityPojo);
+        serviceInjector.injectServicesInto(entityPojo);
+        val entity = objectManager.adapt(entityPojo);
+        entityChangeTracker.enlistDeleting(entity);
+    }
+
+    @PostPersist
+    private void onPostPersist(Object entityPojo) {
+        log.debug("onPostPersist: {}", entityPojo);
+        val entity = objectManager.adapt(entityPojo);
+        entityChangeTracker.enlistCreated(entity);
+    }
+
+    @PostUpdate
+    private void onPostUpdate(Object entityPojo) {
+        log.debug("onPostUpdate: {}", entityPojo);
+        val entity = objectManager.adapt(entityPojo);
+        entityChangeTracker.recognizeUpdating(entity);
+    }
+
+    @PostRemove
+    private void onPostRemove(Object entityPojo) {
+        log.debug("onPostRemove: {}", entityPojo);
+    }
+
+    @PostLoad
+    private void onPostLoad(Object entityPojo) {
+        log.debug("onPostLoad: {}", entityPojo);
+        serviceInjector.injectServicesInto(entityPojo);
+        val entity = objectManager.adapt(entityPojo);
+        entityChangeTracker.recognizeLoaded(entity);
+    }
+
+}
diff --git a/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/JpaEntityInjectionPointResolver.java b/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/JpaEntityInjectionPointResolver.java
index b6d5085..607af96 100644
--- a/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/JpaEntityInjectionPointResolver.java
+++ b/persistence/jpa/applib/src/main/java/org/apache/isis/persistence/jpa/applib/integration/JpaEntityInjectionPointResolver.java
@@ -18,55 +18,13 @@
  */
 package org.apache.isis.persistence.jpa.applib.integration;
 
-import javax.inject.Inject;
-import javax.persistence.PostLoad;
-import javax.persistence.PostPersist;
-import javax.persistence.PostRemove;
-import javax.persistence.PostUpdate;
-import javax.persistence.PrePersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PreUpdate;
-
-import org.apache.isis.applib.services.inject.ServiceInjector;
-
 import lombok.extern.log4j.Log4j2;
 
 /**
- * EntityListener class for listing with the {@link javax.persistence.EntityListeners} annotation, to
- * support injection point resolving for entities.
- * <p>
- * Instances of this class are not managed by Spring, but by the persistence layer.
- * <p>
- * The particular persistence layer implementation in use needs to be configured,
- * with a BeanManager, that is able to resolve injection points for this EntityListener.
- *
- * @since 2.0 {@index}
+ * Use {@link IsisEntityListener} instead.
  */
+@Deprecated
 @Log4j2
-public class JpaEntityInjectionPointResolver {
-
-    @Inject // not managed by Spring (directly)
-    private ServiceInjector serviceInjector;
-
-    @PrePersist
-    @PreUpdate
-    @PreRemove
-    private void beforeAnyUpdate(Object entityPojo) {
-        log.debug("beforeAnyUpdate: {}", entityPojo);
-        serviceInjector.injectServicesInto(entityPojo);
-    }
-
-    @PostPersist
-    @PostUpdate
-    @PostRemove
-    private void afterAnyUpdate(Object entityPojo) {
-        log.debug("afterAnyUpdate: {}", entityPojo);
-    }
-
-    @PostLoad
-    private void afterLoad(Object entityPojo) {
-        log.debug("afterLoad: {}", entityPojo);
-        serviceInjector.injectServicesInto(entityPojo);
-    }
+public class JpaEntityInjectionPointResolver extends IsisEntityListener {
 
 }
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionBoundaryProbe.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionBoundaryProbe.java
index 1b0d317..ca75643 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionBoundaryProbe.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/InteractionBoundaryProbe.java
@@ -24,8 +24,10 @@ import javax.inject.Inject;
 
 import org.junit.jupiter.api.Assertions;
 import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.core.interaction.scope.InteractionScopeAware;
 import org.apache.isis.core.transaction.events.TransactionAfterCompletionEvent;
@@ -56,14 +58,14 @@ public class InteractionBoundaryProbe implements InteractionScopeAware {
     }
 
     /** TRANSACTION BEGIN BOUNDARY */
-    @EventListener(TransactionBeforeCompletionEvent.class)
+    @EventListener(TransactionBeforeCompletionEvent.class) @Order(PriorityPrecedence.FIRST + 100)
     public void onTransactionEnding(TransactionBeforeCompletionEvent event) {
         log.debug("txStarted");
         kvStoreForTesting.incrementCounter(InteractionBoundaryProbe.class, "txEnding");
     }
 
     /** TRANSACTION END BOUNDARY */
-    @EventListener(TransactionAfterCompletionEvent.class)
+    @EventListener(TransactionAfterCompletionEvent.class) @Order(PriorityPrecedence.LAST - 100)
     public void onTransactionEnded(TransactionAfterCompletionEvent event) {
         if(event.isRolledBack()) {
             kvStoreForTesting.incrementCounter(InteractionBoundaryProbe.class, "txRolledBack");

[isis] 09/11: ISIS-2789: amends _PropertyChangeRecord so picks up changes for JPA deleted

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit e8a60ee0266a19afce38a379cec5fa2852bbe9b9
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:34:43 2021 +0100

    ISIS-2789: amends _PropertyChangeRecord so picks up changes for JPA deleted
    
    we use "detached" as close enough.
---
 .../isis/core/transaction/changetracking/_PropertyChangeRecord.java   | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/_PropertyChangeRecord.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/_PropertyChangeRecord.java
index bfc066b..54f2fc4 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/_PropertyChangeRecord.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/changetracking/_PropertyChangeRecord.java
@@ -73,9 +73,7 @@ final class _PropertyChangeRecord {
     }
 
     void updatePostValue() {
-        preAndPostValue = EntityUtil.isRemoved(entity)
-                // don't touch the object!!!
-                // JDO, for example, will complain otherwise...
+        preAndPostValue = EntityUtil.isDetachedOrRemoved(entity)
                 ? preAndPostValue.withPost(IsisTransactionPlaceholder.DELETED)
                 : preAndPostValue.withPost(getPropertyValue());
     }

[isis] 06/11: ISIS-2789: converts Sets to a map, keyed by propertyId

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f175c5d2f770a11b6b22e33c0683ed5e819849f7
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:11:21 2021 +0100

    ISIS-2789: converts Set<ProprttyChangeRecord>s to a map, keyed by propertyId
---
 .../changetracking/EntityChangeTrackerDefault.java           | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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 58bba51..9fb8e9c 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
@@ -103,7 +103,7 @@ implements
     /**
      * Contains initial change records having set the pre-values of every property of every object that was enlisted.
      */
-    private final Set<_PropertyChangeRecord> entityPropertyChangeRecords = _Sets.newLinkedHashSet();
+    private final Map<String,_PropertyChangeRecord> entityPropertyChangeRecords = _Maps.newLinkedHashMap();
 
     /**
      * Contains pre- and post- values of every property of every object that actually changed. A lazy snapshot,
@@ -321,10 +321,10 @@ implements
         entity.getSpecification().streamProperties(MixedIn.EXCLUDED)
         .filter(property->!property.isNotPersisted())
         .map(property->_PropertyChangeRecord.of(entity, property))
-        .filter(record->!entityPropertyChangeRecords.contains(record)) // already enlisted, so ignore
+        .filter(record->!entityPropertyChangeRecords.containsKey(record.getPropertyId())) // already enlisted, so ignore
         .forEach(record->{
             fun.accept(record);
-            entityPropertyChangeRecords.add(record);
+            entityPropertyChangeRecords.put(record.getPropertyId(), record);
         });
     }
 
@@ -334,9 +334,9 @@ implements
      */
     private Set<_PropertyChangeRecord> capturePostValuesAndDrain() {
 
-        val records = entityPropertyChangeRecords.stream()
+        val records = entityPropertyChangeRecords.values().stream()
                 // set post values, which have been left empty up to now
-                .peek(managedProperty->managedProperty.updatePostValue())
+                .peek(_PropertyChangeRecord::updatePostValue)
                 .filter(managedProperty->managedProperty.getPreAndPostValue().shouldPublish())
                 .collect(_Sets.toUnmodifiable());
 
@@ -348,7 +348,7 @@ implements
 
     // side-effect free, used by XRay
     long countPotentialPropertyChangeRecords() {
-        return entityPropertyChangeRecords.stream().count();
+        return entityPropertyChangeRecords.size();
     }
 
     // -- METRICS SERVICE

[isis] 02/11: ISIS-2789: wip - hacking

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit ad4e2faab00e51d53dfa2ea95b7b05b2e4d3867c
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 08:26:52 2021 +0100

    ISIS-2789: wip - hacking
---
 .../changetracking/EntityChangeTrackerDefault.java | 29 +++++++++++++++++++---
 .../ui/components/markup/MarkupFieldFactory.java   |  3 +--
 .../jpa/applib/integration/IsisEntityListener.java | 10 ++++++--
 3 files changed, 34 insertions(+), 8 deletions(-)

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 ce2f01a..102f662 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
@@ -25,6 +25,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Consumer;
 
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.annotation.Priority;
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -96,10 +98,6 @@ implements
     HasEnlistedEntityPropertyChanges,
     HasEnlistedEntityChanges {
 
-    @Inject private EntityPropertyChangePublisher entityPropertyChangePublisher;
-    @Inject private EntityChangesPublisher entityChangesPublisher;
-    @Inject private EventBusService eventBusService;
-    @Inject private Provider<InteractionProvider> interactionProviderProvider;
 
     /**
      * Contains initial change records having set the pre-values of every property of every object that was enlisted.
@@ -116,6 +114,29 @@ implements
     @Getter(AccessLevel.PACKAGE)
     private final Map<Bookmark, EntityChangeKind> changeKindByEnlistedAdapter = _Maps.newLinkedHashMap();
 
+    private final EntityPropertyChangePublisher entityPropertyChangePublisher;
+    private final EntityChangesPublisher entityChangesPublisher;
+    private final EventBusService eventBusService;
+    private final Provider<InteractionProvider> interactionProviderProvider;
+
+    @Inject
+    public EntityChangeTrackerDefault(EntityPropertyChangePublisher entityPropertyChangePublisher, EntityChangesPublisher entityChangesPublisher, EventBusService eventBusService, Provider<InteractionProvider> interactionProviderProvider) {
+        this.entityPropertyChangePublisher = entityPropertyChangePublisher;
+        this.entityChangesPublisher = entityChangesPublisher;
+        this.eventBusService = eventBusService;
+        this.interactionProviderProvider = interactionProviderProvider;
+    }
+
+    @PostConstruct
+    public void postConstruct() {
+
+    }
+
+    @PreDestroy
+    public void preDestroy() {
+
+    }
+
     private boolean isEnlisted(final @NonNull ManagedObject adapter) {
         return ManagedObjects.bookmark(adapter)
         .map(changeKindByEnlistedAdapter::containsKey)
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/markup/MarkupFieldFactory.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/markup/MarkupFieldFactory.java
index e1e77fe..98160ae 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/markup/MarkupFieldFactory.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/markup/MarkupFieldFactory.java
@@ -23,7 +23,6 @@ import java.util.function.Consumer;
 
 import javax.inject.Inject;
 
-import org.springframework.core.annotation.Order;
 import org.w3c.dom.events.EventTarget;
 import org.w3c.dom.html.HTMLAnchorElement;
 
@@ -33,8 +32,8 @@ import org.apache.isis.incubator.viewer.javafx.ui.components.UiComponentHandlerF
 import org.apache.isis.viewer.common.model.components.UiComponentFactory.ComponentRequest;
 
 import lombok.RequiredArgsConstructor;
-import lombok.val;
 import lombok.extern.log4j.Log4j2;
+import lombok.val;
 
 import javafx.application.HostServices;
 import javafx.application.Platform;
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 a9b0af2..6d3dfe6 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
@@ -31,8 +31,8 @@ import org.apache.isis.applib.services.inject.ServiceInjector;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.transaction.changetracking.EntityChangeTracker;
 
-import lombok.val;
 import lombok.extern.log4j.Log4j2;
+import lombok.val;
 
 /**
  * EntityListener class for listing with the {@link javax.persistence.EntityListeners} annotation, to
@@ -54,7 +54,13 @@ public class IsisEntityListener {
 
     // not managed by Spring (directly)
     @Inject private ServiceInjector serviceInjector;
-    @Inject private EntityChangeTracker entityChangeTracker;
+    private EntityChangeTracker entityChangeTracker;
+
+    @Inject
+    public void setEntityChangeTracker(EntityChangeTracker entityChangeTracker) {
+        this.entityChangeTracker = entityChangeTracker;
+    }
+
     @Inject private ObjectManager objectManager;
 
 

[isis] 03/11: ISIS-2789: copies InteractionScope to InteractionScopeHACK prior to rebase

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit afd4fe5d60fa681b0411c83338eccf31bbcb4bf6
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 08:30:42 2021 +0100

    ISIS-2789: copies InteractionScope to InteractionScopeHACK prior to rebase
---
 .../interaction/scope/InteractionScopeHACK.java    | 174 +++++++++++++++++++++
 1 file changed, 174 insertions(+)

diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
new file mode 100644
index 0000000..4b5d39e
--- /dev/null
+++ b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
@@ -0,0 +1,174 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.interaction.scope;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.config.Scope;
+
+import org.apache.isis.applib.services.iactnlayer.InteractionLayerTracker;
+import org.apache.isis.commons.internal.debug._Probe;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+import lombok.Data;
+import lombok.extern.log4j.Log4j2;
+import lombok.val;
+
+/**
+ * @since 2.0
+ */
+@Log4j2
+class InteractionScopeHACK implements Scope, InteractionScopeLifecycleHandler {
+
+    @Inject private InteractionLayerTracker iInteractionLayerTracker;
+
+    @Data(staticConstructor = "of")
+    private static class ScopedObject {
+        final String name;
+        Object instance;
+        Runnable destructionCallback;
+        void preDestroy() {
+            log.debug("destroy isis-interaction scoped {}", name);
+            if(destructionCallback!=null) {
+                destructionCallback.run();
+            }
+        }
+    }
+
+
+    static class ScopedObjects extends HashMap<String, ScopedObject> {
+    }
+
+    @Override
+    public Object get(String name, ObjectFactory<?> objectFactory) {
+
+        ensureInteractionLayerTrackerInjected();
+
+        if(!iInteractionLayerTracker.isInInteraction()) {
+            throw _Exceptions.illegalState("Creation of bean %s with @InteractionScope requires the "
+                    + "calling %s to have an open Interaction on the thread-local stack. Running into "
+                    + "this issue might be caused by use of ... @Inject MyScopedBean bean ..., instead of "
+                    + "... @Inject Provider<MyScopedBean> provider ...", name, _Probe.currentThreadId());
+        }
+
+        val interaction = iInteractionLayerTracker.currentInteractionElseFail();
+        val scopedObjects = interaction.computeAttributeIfAbsent(ScopedObjects.class, clazz -> new ScopedObjects());
+
+        val existingScopedObject = scopedObjects.get(name);
+        if(existingScopedObject!=null) {
+            return existingScopedObject.getInstance();
+        }
+
+        val newScopedObject = ScopedObject.of(name);
+        scopedObjects.put(name, newScopedObject); // just set a stub with a name only
+
+        log.debug("create new isis-interaction scoped {}", name);
+        newScopedObject.setInstance(objectFactory.getObject()); // triggers call to registerDestructionCallback
+
+        return newScopedObject.getInstance();
+    }
+
+
+    @Override
+    public Object remove(final String name) {
+        ensureInteractionLayerTrackerInjected();
+        return iInteractionLayerTracker.currentInteraction()
+                .map(interaction -> {
+                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
+                    if (scopedObjects == null) {
+                        return null;
+                    }
+                    ScopedObject removedIfAny = scopedObjects.remove(name);
+                    if(scopedObjects.isEmpty()) {
+                        interaction.removeAttribute(ScopedObjects.class);
+                    }
+                    if (removedIfAny == null) {
+                        return null;
+                    }
+                    // javadoc for Scope says to remove destruction callback.
+                    removedIfAny.destructionCallback = null;
+                    return removedIfAny.instance;
+                })
+                .orElse(null);
+    }
+
+    private void ensureInteractionLayerTrackerInjected() {
+        if (iInteractionLayerTracker == null) {
+            throw _Exceptions.illegalState("Management of beans with @InteractionScope requires the "
+                    + "InteractionScopeBeanFactoryPostProcessor registered and initialized.");
+        }
+    }
+
+    @Override
+    public void registerDestructionCallback(String name, Runnable callback) {
+        ensureInteractionLayerTrackerInjected();
+        iInteractionLayerTracker.currentInteraction()
+                .ifPresent(interaction -> {
+                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
+                    if (scopedObjects == null) {
+                        return;
+                    }
+                    final ScopedObject scopedObject = scopedObjects.get(name);
+                    if (scopedObject == null) {
+                        return;
+                    }
+                    scopedObject.destructionCallback = callback;
+                });
+    }
+
+    @Override
+    public Object resolveContextualObject(String key) {
+        // null by convention if not supported
+        return null;
+    }
+
+    @Override
+    public String getConversationId() {
+        // null by convention if not supported
+        return iInteractionLayerTracker.getInteractionId()
+                .map(UUID::toString)
+                .orElse(null);
+    }
+
+    @Override
+    public void onTopLevelInteractionOpened() {
+        // nothing to do
+    }
+
+    @Override
+    public void onTopLevelInteractionClosing() {
+        ensureInteractionLayerTrackerInjected();
+        iInteractionLayerTracker.currentInteraction()
+                .ifPresent(interaction -> {
+                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
+                    if (scopedObjects == null) {
+                        return;
+                    }
+                    val scopedObjectValues = scopedObjects.values();
+                    scopedObjectValues.forEach(ScopedObject::preDestroy);
+                    scopedObjects.clear();
+                    interaction.removeAttribute(ScopedObjects.class);
+                });
+    }
+
+}

[isis] 11/11: ISIS-2789: removes my hacked version of InteractionScope as Andi's fix seemed to do the job

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit b940e514bdbe8720bcc2e888ae17fe8dcfd9922d
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:35:24 2021 +0100

    ISIS-2789: removes my hacked version of InteractionScope as Andi's fix seemed to do the job
---
 .../interaction/scope/InteractionScopeHACK.java    | 187 ---------------------
 1 file changed, 187 deletions(-)

diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
deleted file mode 100644
index 3a3c590..0000000
--- a/core/interaction/src/main/java/org/apache/isis/core/interaction/scope/InteractionScopeHACK.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.interaction.scope;
-
-import java.util.HashMap;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.springframework.beans.factory.ObjectFactory;
-import org.springframework.beans.factory.config.Scope;
-
-import org.apache.isis.applib.services.iactnlayer.InteractionLayerTracker;
-import org.apache.isis.commons.internal.debug._Probe;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-
-import lombok.Data;
-import lombok.extern.log4j.Log4j2;
-import lombok.val;
-
-/**
- * @since 2.0
- */
-@Log4j2
-class InteractionScopeHACK implements Scope, InteractionScopeLifecycleHandler {
-
-    @Inject private InteractionLayerTracker iInteractionLayerTracker;
-
-    @Data(staticConstructor = "of")
-    private static class ScopedObject {
-        final String name;
-        Object instance;
-        Runnable destructionCallback;
-        void preDestroy() {
-            log.debug("destroy isis-interaction scoped {}", name);
-            if(destructionCallback!=null) {
-                destructionCallback.run();
-            }
-        }
-    }
-
-
-    static class ScopedObjects extends HashMap<String, ScopedObject> {
-    }
-
-    @Override
-    public Object get(String name, ObjectFactory<?> objectFactory) {
-
-        ensureInteractionLayerTrackerInjected();
-
-        if(!iInteractionLayerTracker.isInInteraction()) {
-            throw _Exceptions.illegalState("Creation of bean %s with @InteractionScope requires the "
-                    + "calling %s to have an open Interaction on the thread-local stack. Running into "
-                    + "this issue might be caused by use of ... @Inject MyScopedBean bean ..., instead of "
-                    + "... @Inject Provider<MyScopedBean> provider ...", name, _Probe.currentThreadId());
-        }
-
-        val interaction = iInteractionLayerTracker.currentInteractionElseFail();
-        val scopedObjects = interaction.computeAttributeIfAbsent(ScopedObjects.class, clazz -> new ScopedObjects());
-
-        val existingScopedObject = scopedObjects.get(name);
-        if(existingScopedObject!=null) {
-            return existingScopedObject.getInstance();
-        }
-
-        val newScopedObject = ScopedObject.of(name);
-        scopedObjects.put(name, newScopedObject); // just set a stub with a name only
-
-        log.debug("create new isis-interaction scoped {}", name);
-        newScopedObject.setInstance(objectFactory.getObject()); // triggers call to registerDestructionCallback
-
-        return newScopedObject.getInstance();
-    }
-
-
-    @Override
-    public Object remove(final String name) {
-        ensureInteractionLayerTrackerInjected();
-        return iInteractionLayerTracker.currentInteraction()
-                .map(interaction -> {
-                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
-                    if (scopedObjects == null) {
-                        return null;
-                    }
-                    ScopedObject removedIfAny = scopedObjects.remove(name);
-                    if(scopedObjects.isEmpty()) {
-                        interaction.removeAttribute(ScopedObjects.class);
-                    }
-                    if (removedIfAny == null) {
-                        return null;
-                    }
-                    // javadoc for Scope says to remove destruction callback.
-                    removedIfAny.destructionCallback = null;
-                    return removedIfAny.instance;
-                })
-                .orElse(null);
-    }
-
-    private void ensureInteractionLayerTrackerInjected() {
-        if (iInteractionLayerTracker == null) {
-            throw _Exceptions.illegalState("Management of beans with @InteractionScope requires the "
-                    + "InteractionScopeBeanFactoryPostProcessor registered and initialized.");
-        }
-    }
-
-    @Override
-    public void registerDestructionCallback(String name, Runnable callback) {
-        ensureInteractionLayerTrackerInjected();
-        iInteractionLayerTracker.currentInteraction()
-                .ifPresent(interaction -> {
-                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
-                    if (scopedObjects == null) {
-                        return;
-                    }
-                    final ScopedObject scopedObject = scopedObjects.get(name);
-                    if (scopedObject == null) {
-                        return;
-                    }
-                    scopedObject.destructionCallback = callback;
-                });
-    }
-
-    @Override
-    public Object resolveContextualObject(String key) {
-        // null by convention if not supported
-        return null;
-    }
-
-    @Override
-    public String getConversationId() {
-        // null by convention if not supported
-        return iInteractionLayerTracker.getInteractionId()
-                .map(UUID::toString)
-                .orElse(null);
-    }
-
-    @Override
-    public void onTopLevelInteractionOpened() {
-        // nothing to do
-    }
-
-    @Override
-    public void onTopLevelInteractionPreDestroy() {
-        ensureInteractionLayerTrackerInjected();
-        iInteractionLayerTracker.currentInteraction()
-                .ifPresent(interaction -> {
-                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
-                    if (scopedObjects == null) {
-                        return;
-                    }
-                    val scopedObjectValues = scopedObjects.values();
-                    scopedObjectValues.forEach(ScopedObject::preDestroy);
-                    scopedObjects.clear();
-                });
-    }
-
-    @Override
-    public void onTopLevelInteractionClosed() {
-        ensureInteractionLayerTrackerInjected();
-        iInteractionLayerTracker.currentInteraction()
-                .ifPresent(interaction -> {
-                    final ScopedObjects scopedObjects = interaction.getAttribute(ScopedObjects.class);
-                    if (scopedObjects == null) {
-                        return;
-                    }
-                    scopedObjects.clear();
-                    interaction.removeAttribute(ScopedObjects.class);
-                });
-    }
-
-}

[isis] 10/11: ISIS-2789: enhances CommandLogger, dump out XML as well.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch ISIS-2789
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 7995ac7e31a2caeca0f51f2af0b9925c31bc2c4e
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jul 6 13:35:01 2021 +0100

    ISIS-2789: enhances CommandLogger, dump out XML as well.
---
 .../applib/services/publishing/log/CommandLogger.java    | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
index 6f51be8..ca78e9e 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
@@ -27,11 +27,13 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
+import org.apache.isis.applib.util.schema.CommandDtoUtils;
 
 import lombok.extern.log4j.Log4j2;
+import lombok.val;
 
 /**
- * 
+ *
  * @since 2.0 {@index}
  */
 @Service
@@ -48,11 +50,15 @@ public class CommandLogger implements CommandSubscriber {
 
     @Override
     public void onCompleted(Command command) {
-        
-        log.debug("completed: {}, systemStateChanged {}",
+
+        val commandDto = command.getCommandDto();
+        val xml = CommandDtoUtils.toXml(commandDto);
+
+        log.debug("completed: {}, systemStateChanged {} \n{}",
                 command.getLogicalMemberIdentifier(),
-                command.isSystemStateChanged());
-        
+                command.isSystemStateChanged(),
+                xml);
+
         //log.debug("completed: {}", command);
     }