This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/main by this push:
new 1f8b579df7e CAUSEWAY-3982: extend auditing to only log on updates, not
create or delete (forwardport from v2 to v4)
1f8b579df7e is described below
commit 1f8b579df7ec0a3a84e41f07898c0db46f6ebfdb
Author: andi-huber <[email protected]>
AuthorDate: Fri Mar 27 06:36:07 2026 +0100
CAUSEWAY-3982: extend auditing to only log on updates, not create or
delete (forwardport from v2 to v4)
---
.../causeway/applib/annotation/Publishing.java | 21 ++-
.../CommandPublishingFacetForActionAnnotation.java | 55 +++----
...ommandPublishingFacetForPropertyAnnotation.java | 80 +++++-----
...xecutionPublishingFacetForActionAnnotation.java | 46 +++---
...cutionPublishingFacetForPropertyAnnotation.java | 82 +++++-----
...gePublishingFacetForDomainObjectAnnotation.java | 35 ++---
...FacetForDomainObjectAnnotationAsConfigured.java | 2 +-
...tityChangePublishingFacetFromConfiguration.java | 2 +-
.../entitychange/EntityChangePublishingFacet.java | 45 ++++--
.../EntityChangePublishingFacetAbstract.java | 12 +-
.../EntityPropertyChangePublishingPolicyFacet.java | 11 +-
...PublishingPolicyFacetForPropertyAnnotation.java | 6 +-
.../metamodel/facets/FacetFactoryTestAbstract.java | 3 +-
.../DomainObjectAnnotationFacetFactoryTest.java | 165 +++++++++++++--------
.../PropertyAnnotationFacetFactoryTest.java | 5 +-
.../changetracking/EntityChangeTrackerDefault.java | 44 +++---
16 files changed, 325 insertions(+), 289 deletions(-)
diff --git
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Publishing.java
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Publishing.java
index b0fcc085537..c6125513cdb 100644
---
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Publishing.java
+++
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Publishing.java
@@ -45,8 +45,8 @@ public enum Publishing {
* Publishing of data triggered by interaction with this object
* should be handled as per the default publishing policy
* configured in <tt>application.properties</tt>.
- * <p>
- * If no publishing policy is configured, then publishing is disabled.
+ *
+ * <p>If no publishing policy is configured, then publishing is disabled.
*/
AS_CONFIGURED,
@@ -55,6 +55,23 @@ public enum Publishing {
*/
ENABLED,
+ /**
+ * Applies only to {@link EntityPropertyChangeSubscriber}, whereby events
are published for modifications to the
+ * object, but no events are published for the initial creation of an
object.
+ *
+ * <p>In the case of audit trail extension,
+ * this effectively suppresses all of the "[NEW] -> value" entries that
are created for every property of the
+ * entity when it is being created, and also all of the "value ->
[DELETED]" entries that are created for every property of the
+ * entity when it is being deleted.
+ *
+ * <p>This variant is intended only where the application code has enough
traceability built into the domain
+ * (perhaps to provide visibility to the end-users) that the technical
auditing is overkill. It will also
+ * of course reduce the volume of auditing, so improves performance
(likely both response times and throughput).
+ *
+ * <p>For other subscribers, behaviour is the same as {@link #ENABLED}.
+ */
+ ENABLED_FOR_UPDATES_ONLY,
+
/**
* Do <b>not</b> publish data triggered by interaction with this object
* (even if otherwise configured to enable publishing).
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForActionAnnotation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForActionAnnotation.java
index c4ec4abb732..b7f35a5f8ae 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForActionAnnotation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForActionAnnotation.java
@@ -62,40 +62,33 @@ public static Optional<CommandPublishingFacet> create(
var publishingPolicy =
ActionConfigOptions.actionCommandPublishingPolicy(configuration);
return actionsIfAny
- .filter(action -> action.commandPublishing() !=
Publishing.NOT_SPECIFIED)
- .map(action -> {
- Publishing publishing = action.commandPublishing();
+ .filter(action -> action.commandPublishing() !=
Publishing.NOT_SPECIFIED)
+ .map(action -> {
+ Publishing publishing = action.commandPublishing();
- final Class<? extends CommandDtoProcessor> processorClass
= action.commandDtoProcessor();
- final CommandDtoProcessor processor =
newProcessorElseNull(processorClass);
+ final Class<? extends CommandDtoProcessor> processorClass =
action.commandDtoProcessor();
+ final CommandDtoProcessor processor =
newProcessorElseNull(processorClass);
- if(processor != null) {
- publishing = Publishing.ENABLED;
- }
+ if(processor != null) {
+ publishing = Publishing.ENABLED;
+ }
- switch (publishing) {
- case AS_CONFIGURED:
- switch (publishingPolicy) {
- case NONE:
- return new
CommandPublishingFacetForActionAnnotationAsConfigured.None(holder,
servicesInjector);
- case IGNORE_QUERY_ONLY:
- case IGNORE_SAFE:
- return Facets.hasSafeSemantics(holder)
- ? new
CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder,
servicesInjector)
- : new
CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder,
servicesInjector);
- case ALL:
- return new
CommandPublishingFacetForActionAnnotationAsConfigured.All(holder,
servicesInjector);
- default:
- throw new
IllegalStateException(String.format("configured action.commandPublishing policy
'%s' not recognised", publishingPolicy));
- }
- case DISABLED:
- return new
CommandPublishingFacetForActionAnnotation.Disabled(processor, holder,
servicesInjector);
- case ENABLED:
- return new
CommandPublishingFacetForActionAnnotation.Enabled(processor, holder,
servicesInjector);
- default:
- throw new
IllegalStateException(String.format("@Action#commandPublishing '%s' not
recognised", publishing));
- }
- });
+ return switch (publishing) {
+ case AS_CONFIGURED -> switch (publishingPolicy) {
+ case NONE -> new
CommandPublishingFacetForActionAnnotationAsConfigured.None(holder,
servicesInjector);
+ case IGNORE_QUERY_ONLY, IGNORE_SAFE ->
Facets.hasSafeSemantics(holder)
+ ? new
CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder,
servicesInjector)
+ : new
CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder,
servicesInjector);
+ case ALL -> new
CommandPublishingFacetForActionAnnotationAsConfigured.All(holder,
servicesInjector);
+ default -> throw new IllegalStateException(
+ String.format("configured
action.commandPublishing policy '%s' not recognised", publishingPolicy));
+ };
+ case DISABLED -> new
CommandPublishingFacetForActionAnnotation.Disabled(processor, holder,
servicesInjector);
+ case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new
CommandPublishingFacetForActionAnnotation.Enabled(processor, holder,
servicesInjector);
+ default -> throw new IllegalStateException(
+ String.format("@Action#commandPublishing '%s' not
recognised", publishing));
+ };
+ });
}
CommandPublishingFacetForActionAnnotation(
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForPropertyAnnotation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForPropertyAnnotation.java
index 873470d9746..642a9edd462 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForPropertyAnnotation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForPropertyAnnotation.java
@@ -68,7 +68,7 @@ public static CommandPublishingFacet create(
return propertyIfAny
.filter(property -> property.commandPublishing() !=
Publishing.NOT_SPECIFIED)
- .map(property -> {
+ .<CommandPublishingFacet>map(property -> {
Publishing publishing = property.commandPublishing();
var processorClass = property.commandDtoProcessor();
@@ -78,64 +78,54 @@ public static CommandPublishingFacet create(
publishing = Publishing.ENABLED;
}
- switch (publishing) {
- case AS_CONFIGURED:
- switch (publishingPolicy) {
- case NONE:
- return (CommandPublishingFacet)new
CommandPublishingFacetForPropertyAnnotationAsConfigured.None(holder,
servicesInjector);
- case ALL:
- return new
CommandPublishingFacetForPropertyAnnotationAsConfigured.All(holder,
servicesInjector);
- default:
- throw new
IllegalStateException(String.format("configured property.commandpublishing
policy '%s' not recognised", publishingPolicy));
- }
- case DISABLED:
- return new
CommandPublishingFacetForPropertyAnnotation.Disabled(processor, holder,
servicesInjector);
- case ENABLED:
- return new
CommandPublishingFacetForPropertyAnnotation.Enabled(processor, holder,
servicesInjector);
- default:
- throw new
IllegalStateException(String.format("@Property#commandPublishing '%s' not
recognised", publishing));
- }
+ return switch (publishing) {
+ case AS_CONFIGURED -> switch (publishingPolicy) {
+ case NONE -> new
CommandPublishingFacetForPropertyAnnotationAsConfigured.None(holder,
servicesInjector);
+ case ALL -> new
CommandPublishingFacetForPropertyAnnotationAsConfigured.All(holder,
servicesInjector);
+ default -> throw new IllegalStateException(
+ String.format("configured
property.commandpublishing policy '%s' not recognised", publishingPolicy));
+ };
+ case DISABLED -> new
CommandPublishingFacetForPropertyAnnotation.Disabled(processor, holder,
servicesInjector);
+ case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new
CommandPublishingFacetForPropertyAnnotation.Enabled(processor, holder,
servicesInjector);
+ default -> throw new IllegalStateException(
+ String.format("@Property#commandPublishing '%s'
not recognised", publishing));
+ };
})
.orElseGet(() -> {
// there is no publishing facet from either @Action or
@Property, so use the appropriate configuration to install a default
- if (representsProperty(holder)) {
+ if (representsProperty(holder))
// we are dealing with a property
- switch (publishingPolicy) {
- case NONE:
- return new
CommandPublishingFacetForPropertyFromConfiguration.None(holder,
servicesInjector);
- case ALL:
- return new
CommandPublishingFacetForPropertyFromConfiguration.All(holder,
servicesInjector);
- default:
- throw new
IllegalStateException(String.format("configured property.commandPublishing
policy '%s' not recognised", publishingPolicy));
- }
- } else {
+ return switch (publishingPolicy) {
+ case NONE -> new
CommandPublishingFacetForPropertyFromConfiguration.None(holder,
servicesInjector);
+ case ALL -> new
CommandPublishingFacetForPropertyFromConfiguration.All(holder,
servicesInjector);
+ default -> throw new
IllegalStateException(String.format("configured property.commandPublishing
policy '%s' not recognised", publishingPolicy));
+ };
+ else {
// we are dealing with an action
var actionPublishingPolicy =
ActionConfigOptions.actionCommandPublishingPolicy(configuration);
- switch (actionPublishingPolicy) {
- case NONE:
- return new
CommandPublishingFacetForActionFromConfiguration.None(holder, servicesInjector);
- case IGNORE_QUERY_ONLY:
- case IGNORE_SAFE:
- return Facets.hasSafeSemantics(holder)
- ? new
CommandPublishingFacetForActionFromConfiguration.IgnoreSafe(holder,
servicesInjector)
- : new
CommandPublishingFacetForActionFromConfiguration.IgnoreSafeYetNot(holder,
servicesInjector);
- case ALL:
- return new
CommandPublishingFacetForActionFromConfiguration.All(holder, servicesInjector);
- default:
- throw new
IllegalStateException(String.format("configured action.commandPublishing policy
'%s' not recognised", actionPublishingPolicy));
- }
+ return switch (actionPublishingPolicy) {
+ case NONE -> new
CommandPublishingFacetForActionFromConfiguration.None(holder, servicesInjector);
+ case IGNORE_QUERY_ONLY, IGNORE_SAFE ->
Facets.hasSafeSemantics(holder)
+ ? new
CommandPublishingFacetForActionFromConfiguration.IgnoreSafe(holder,
servicesInjector)
+ : new
CommandPublishingFacetForActionFromConfiguration.IgnoreSafeYetNot(holder,
servicesInjector);
+ case ALL -> new
CommandPublishingFacetForActionFromConfiguration.All(holder, servicesInjector);
+ default -> throw new
IllegalStateException(String.format("configured action.commandPublishing policy
'%s' not recognised", actionPublishingPolicy));
+ };
}
});
+
}
private static boolean representsProperty(final FacetHolder holder) {
// a property
- if (holder instanceof TypedFacetHolder &&
((TypedFacetHolder)holder).featureType() == FeatureType.PROPERTY) {
+ if (holder instanceof TypedFacetHolder typedFacetHolder
+ && typedFacetHolder.featureType() == FeatureType.PROPERTY)
return true;
- }
// or a mixin
- return holder.containsFacet(ContributingFacet.class) &&
- holder.getFacet(ContributingFacet.class).contributed() ==
MixinFacet.Contributing.AS_PROPERTY;
+ return holder.lookupFacet(ContributingFacet.class)
+ .map(ContributingFacet::contributed)
+ .map(MixinFacet.Contributing.AS_PROPERTY::equals)
+ .orElse(false);
}
CommandPublishingFacetForPropertyAnnotation(
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForActionAnnotation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForActionAnnotation.java
index 14b780a8d5f..67b52d6bdb8 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForActionAnnotation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForActionAnnotation.java
@@ -58,34 +58,24 @@ public static Optional<ExecutionPublishingFacet> create(
var publishingPolicy =
ActionConfigOptions.actionExecutionPublishingPolicy(configuration);
- return
- actionsIfAny
- .filter(action -> action.executionPublishing() !=
Publishing.NOT_SPECIFIED)
- .map(Action::executionPublishing)
- .<ExecutionPublishingFacet>map(publishing -> {
- switch (publishing) {
- case AS_CONFIGURED:
- switch (publishingPolicy) {
- case NONE:
- return new
ExecutionPublishingFacetForActionAnnotationAsConfigured.None(holder);
- case IGNORE_QUERY_ONLY:
- case IGNORE_SAFE:
- return Facets.hasSafeSemantics(holder)
- ? new
ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder)
- : new
ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder);
- case ALL:
- return new
ExecutionPublishingFacetForActionAnnotationAsConfigured.All(holder);
- default:
- throw new
IllegalStateException(String.format("configured action.executionPublishing
policy '%s' not recognised", publishingPolicy));
- }
- case DISABLED:
- return new
ExecutionPublishingFacetForActionAnnotation.Disabled(holder);
- case ENABLED:
- return new
ExecutionPublishingFacetForActionAnnotation.Enabled(holder);
- default:
- throw new
IllegalStateException(String.format("@Action#executionPublishing '%s' not
recognised", publishing));
- }
- });
+ return actionsIfAny
+ .filter(action -> action.executionPublishing() !=
Publishing.NOT_SPECIFIED)
+ .map(Action::executionPublishing)
+ .<ExecutionPublishingFacet>map(publishing -> (switch (publishing) {
+ case AS_CONFIGURED -> switch (publishingPolicy) {
+ case NONE -> new
ExecutionPublishingFacetForActionAnnotationAsConfigured.None(holder);
+ case IGNORE_QUERY_ONLY, IGNORE_SAFE ->
Facets.hasSafeSemantics(holder)
+ ? new
ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder)
+ : new
ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder);
+ case ALL -> new
ExecutionPublishingFacetForActionAnnotationAsConfigured.All(holder);
+ default -> throw new IllegalStateException(
+ String.format("configured
action.executionPublishing policy '%s' not recognised", publishingPolicy));
+ };
+ case DISABLED -> new
ExecutionPublishingFacetForActionAnnotation.Disabled(holder);
+ case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new
ExecutionPublishingFacetForActionAnnotation.Enabled(holder);
+ default -> throw new IllegalStateException(
+ String.format("@Action#executionPublishing '%s' not
recognised", publishing));
+ }));
}
ExecutionPublishingFacetForActionAnnotation(final FacetHolder holder) {
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForPropertyAnnotation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForPropertyAnnotation.java
index ec9fcc705df..f08b54d6e34 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForPropertyAnnotation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForPropertyAnnotation.java
@@ -67,66 +67,54 @@ public static ExecutionPublishingFacet create(
return propertyIfAny
.map(Property::executionPublishing)
.filter(publishing -> publishing != Publishing.NOT_SPECIFIED)
- .map(publishing -> {
-
- switch (publishing) {
- case AS_CONFIGURED:
- switch (publishingPolicy) {
- case NONE:
- return (ExecutionPublishingFacet)new
ExecutionPublishingFacetForPropertyAnnotationAsConfigured.None(holder);
- case ALL:
- return new
ExecutionPublishingFacetForPropertyAnnotationAsConfigured.All(holder);
- default:
- throw new
IllegalStateException(String.format("configured property.executionPublishing
policy '%s' not recognised", publishingPolicy));
- }
- case DISABLED:
- return new
ExecutionPublishingFacetForPropertyAnnotation.Disabled(holder);
- case ENABLED:
- return new
ExecutionPublishingFacetForPropertyAnnotation.Enabled(holder);
- default:
- throw new
IllegalStateException(String.format("@Property#executionPublishing '%s' not
recognised", publishing));
- }
- })
+ .<ExecutionPublishingFacet>map(publishing -> (switch (publishing) {
+ case AS_CONFIGURED -> switch (publishingPolicy) {
+ case NONE -> new
ExecutionPublishingFacetForPropertyAnnotationAsConfigured.None(holder);
+ case ALL -> new
ExecutionPublishingFacetForPropertyAnnotationAsConfigured.All(holder);
+ default -> throw new IllegalStateException(
+ String.format("configured property.executionPublishing
policy '%s' not recognised", publishingPolicy));
+ };
+ case DISABLED -> new
ExecutionPublishingFacetForPropertyAnnotation.Disabled(holder);
+ case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new
ExecutionPublishingFacetForPropertyAnnotation.Enabled(holder);
+ default -> throw new IllegalStateException(
+ String.format("@Property#executionPublishing '%s' not
recognised", publishing));
+ }))
.orElseGet(() -> {
// there is no publishing facet from either @Action or
@Property, so use the appropriate configuration to install a default
- if (representsProperty(holder)) {
+ if (representsProperty(holder))
// we are dealing with a property
- switch (publishingPolicy) {
- case NONE:
- return new
ExecutionPublishingFacetForPropertyFromConfiguration.None(holder);
- case ALL:
- return new
ExecutionPublishingFacetForPropertyFromConfiguration.All(holder);
- default:
- throw new
IllegalStateException(String.format("configured property.executionPublishing
policy '%s' not recognised", publishingPolicy));
- }
- } else {
+ return switch (publishingPolicy) {
+ case NONE -> new
ExecutionPublishingFacetForPropertyFromConfiguration.None(holder);
+ case ALL -> new
ExecutionPublishingFacetForPropertyFromConfiguration.All(holder);
+ default -> throw new IllegalStateException(
+ String.format("configured
property.executionPublishing policy '%s' not recognised", publishingPolicy));
+ };
+ else {
// we are dealing with an action
var actionPublishingPolicy =
ActionConfigOptions.actionExecutionPublishingPolicy(configuration);
- switch (actionPublishingPolicy) {
- case NONE:
- return new
ExecutionPublishingFacetForActionFromConfiguration.None(holder);
- case IGNORE_QUERY_ONLY:
- case IGNORE_SAFE:
- return Facets.hasSafeSemantics(holder)
- ? new
ExecutionPublishingFacetForActionFromConfiguration.IgnoreSafe(holder)
- : new
ExecutionPublishingFacetForActionFromConfiguration.IgnoreSafeYetNot(holder);
- case ALL:
- return new
ExecutionPublishingFacetForActionFromConfiguration.All(holder);
- default:
- throw new
IllegalStateException(String.format("configured action.executionPublishing
policy '%s' not recognised", actionPublishingPolicy));
- }
+ return switch (actionPublishingPolicy) {
+ case NONE -> new
ExecutionPublishingFacetForActionFromConfiguration.None(holder);
+ case IGNORE_QUERY_ONLY, IGNORE_SAFE ->
Facets.hasSafeSemantics(holder)
+ ? new
ExecutionPublishingFacetForActionFromConfiguration.IgnoreSafe(holder)
+ : new
ExecutionPublishingFacetForActionFromConfiguration.IgnoreSafeYetNot(holder);
+ case ALL -> new
ExecutionPublishingFacetForActionFromConfiguration.All(holder);
+ default -> throw new IllegalStateException(
+ String.format("configured
action.executionPublishing policy '%s' not recognised",
actionPublishingPolicy));
+ };
}
});
}
private static boolean representsProperty(final FacetHolder holder) {
// a property
- if (holder instanceof TypedFacetHolder &&
((TypedFacetHolder)holder).featureType() == FeatureType.PROPERTY) {
+ if (holder instanceof TypedFacetHolder typedFacetHolder
+ && typedFacetHolder.featureType() == FeatureType.PROPERTY)
return true;
- }
// or a mixin
- return holder.containsFacet(ContributingFacet.class) &&
- holder.getFacet(ContributingFacet.class).contributed() ==
MixinFacet.Contributing.AS_PROPERTY;
+ return holder.lookupFacet(ContributingFacet.class)
+ .map(ContributingFacet::contributed)
+ .map(MixinFacet.Contributing.AS_PROPERTY::equals)
+ .orElse(false);
}
public ExecutionPublishingFacetForPropertyAnnotation(final FacetHolder
holder) {
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotation.java
index 9956501d41c..56a686b2250 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotation.java
@@ -38,32 +38,27 @@ public static Optional<EntityChangePublishingFacet> create(
var publish =
entityChangePublishingIfAny.orElse(Publishing.AS_CONFIGURED);
- switch (publish) {
- case NOT_SPECIFIED:
- case AS_CONFIGURED:
-
- var publishingPolicy =
DomainObjectConfigOptions.entityChangePublishingPolicy(configuration);
- switch (publishingPolicy) {
- case NONE:
- return Optional.of(entityChangePublishingIfAny.isPresent()
+ return switch (publish) {
+ case NOT_SPECIFIED, AS_CONFIGURED -> {
+ var publishingPolicy =
DomainObjectConfigOptions.entityChangePublishingPolicy(configuration);
+ yield switch (publishingPolicy) {
+ case NONE ->
Optional.of(entityChangePublishingIfAny.isPresent()
? new
EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured(holder, false)
: new
EntityChangePublishingFacetFromConfiguration(holder, false));
- default:
- return Optional.of(entityChangePublishingIfAny.isPresent()
+ default ->
Optional.of(entityChangePublishingIfAny.isPresent()
? new
EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured(holder, true)
: new
EntityChangePublishingFacetFromConfiguration(holder, true));
+ };
}
- case DISABLED:
- return Optional.of(new
EntityChangePublishingFacetForDomainObjectAnnotation(holder, false));
- case ENABLED:
- return Optional.of(new
EntityChangePublishingFacetForDomainObjectAnnotation(holder, true));
-
- default:
- throw _Exceptions.unmatchedCase(publish);
- }
+ case DISABLED -> Optional.of(new
EntityChangePublishingFacetForDomainObjectAnnotation(holder, false, false,
false, false));
+ case ENABLED -> Optional.of(new
EntityChangePublishingFacetForDomainObjectAnnotation(holder, true, true, true,
true));
+ case ENABLED_FOR_UPDATES_ONLY -> Optional.of(new
EntityChangePublishingFacetForDomainObjectAnnotation(holder, true, false, true,
false));
+ default -> throw _Exceptions.unmatchedCase(publish);
+ };
}
- protected EntityChangePublishingFacetForDomainObjectAnnotation(final
FacetHolder holder, boolean enabled) {
- super(holder, enabled);
+ protected EntityChangePublishingFacetForDomainObjectAnnotation(final
FacetHolder holder, final boolean enabled,
+ final boolean enabledForCreate, final boolean enabledForUpdate,
final boolean enabledForDelete) {
+ super(holder, enabled, enabledForCreate, enabledForUpdate,
enabledForDelete);
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured.java
index df5890d9df7..e724d79135d 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured.java
@@ -23,7 +23,7 @@
public class EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured
extends EntityChangePublishingFacetForDomainObjectAnnotation {
public
EntityChangePublishingFacetForDomainObjectAnnotationAsConfigured(final
FacetHolder facetHolder, final boolean enabled) {
- super(facetHolder, enabled);
+ super(facetHolder, enabled, enabled, enabled, enabled);
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetFromConfiguration.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetFromConfiguration.java
index cdeebda521c..0ef4aef74cf 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetFromConfiguration.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/domainobject/entitychangepublishing/EntityChangePublishingFacetFromConfiguration.java
@@ -30,7 +30,7 @@ public class EntityChangePublishingFacetFromConfiguration
extends EntityChangePublishingFacetAbstract {
public EntityChangePublishingFacetFromConfiguration(final FacetHolder
facetHolder, final boolean enabled) {
- super(facetHolder, enabled);
+ super(facetHolder, enabled, enabled, enabled, enabled);
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacet.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacet.java
index 91513f3bee0..c8b869cdc12 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacet.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacet.java
@@ -18,6 +18,8 @@
*/
package org.apache.causeway.core.metamodel.facets.object.publish.entitychange;
+import java.util.Optional;
+
import org.apache.causeway.core.metamodel.facetapi.Facet;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
@@ -30,22 +32,41 @@
*/
public interface EntityChangePublishingFacet extends Facet {
- public static boolean isPublishingEnabled(final FacetHolder facetHolder) {
- if(facetHolder==null) {
- return false;
- }
+ static boolean isPublishingEnabled(final FacetHolder facetHolder) {
+ return entityChangePublishingFacet(facetHolder)
+ .map(EntityChangePublishingFacet::isEnabled)
+ .orElse(false);
+ }
+
+ static boolean isPublishingEnabledForCreate(final FacetHolder facetHolder)
{
+ return entityChangePublishingFacet(facetHolder)
+ .map(EntityChangePublishingFacet::isEnabledForCreate)
+ .orElse(false);
+ }
- if(facetHolder instanceof ObjectSpecification) {
- if(!((ObjectSpecification)facetHolder).isEntity()) {
- return false;
- }
- }
+ static boolean isPublishingEnabledForUpdate(final FacetHolder facetHolder)
{
+ return entityChangePublishingFacet(facetHolder)
+ .map(EntityChangePublishingFacet::isEnabledForUpdate)
+ .orElse(false);
+ }
- var entityChangePublishingFacet =
facetHolder.getFacet(EntityChangePublishingFacet.class);
- return entityChangePublishingFacet != null
- && entityChangePublishingFacet.isEnabled();
+ static boolean isPublishingEnabledForDelete(final FacetHolder facetHolder)
{
+ return entityChangePublishingFacet(facetHolder)
+ .map(EntityChangePublishingFacet::isEnabledForDelete)
+ .orElse(false);
}
boolean isEnabled();
+ boolean isEnabledForCreate();
+ boolean isEnabledForUpdate();
+ boolean isEnabledForDelete();
+ private static Optional<EntityChangePublishingFacet>
entityChangePublishingFacet(final FacetHolder facetHolder) {
+ if(facetHolder==null)
+ return Optional.empty();
+ if(facetHolder instanceof ObjectSpecification objSpepc
+ && !objSpepc.isEntity())
+ return Optional.empty(); // optimization
+ return facetHolder.lookupFacet(EntityChangePublishingFacet.class);
+ }
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacetAbstract.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacetAbstract.java
index af60b3f0544..20ce78bf62f 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacetAbstract.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/publish/entitychange/EntityChangePublishingFacetAbstract.java
@@ -32,12 +32,18 @@ private static final Class<? extends Facet> type() {
return EntityChangePublishingFacet.class;
}
- @Getter
- private final boolean enabled;
+ @Getter private final boolean enabled;
+ @Getter private final boolean enabledForCreate;
+ @Getter private final boolean enabledForUpdate;
+ @Getter private final boolean enabledForDelete;
- public EntityChangePublishingFacetAbstract(final FacetHolder facetHolder,
boolean enabled) {
+ public EntityChangePublishingFacetAbstract(final FacetHolder facetHolder,
final boolean enabled,
+ final boolean enabledForCreate, final boolean enabledForUpdate,
final boolean enabledForDelete) {
super(EntityChangePublishingFacetAbstract.type(), facetHolder);
this.enabled = enabled;
+ this.enabledForCreate = enabledForCreate;
+ this.enabledForUpdate = enabledForUpdate;
+ this.enabledForDelete = enabledForDelete;
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacet.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacet.java
index 6eca0d5a86a..4ea8c167ac0 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacet.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacet.java
@@ -18,14 +18,14 @@
*/
package
org.apache.causeway.core.metamodel.facets.properties.property.entitychangepublishing;
+import org.jspecify.annotations.NonNull;
+
import org.apache.causeway.applib.annotation.Publishing;
import org.apache.causeway.applib.value.Blob;
import org.apache.causeway.applib.value.Clob;
import org.apache.causeway.core.metamodel.facetapi.Facet;
import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
-import org.jspecify.annotations.NonNull;
-
/**
* Indicates whether a property should be excluded from entity change
publishing (auditing).
* @since 2.0
@@ -33,7 +33,7 @@
public interface EntityPropertyChangePublishingPolicyFacet extends Facet {
/**
- * Must be one of Publishing.ENABLED or Publishing.DISABLED.
+ * Must be one of {@link Publishing#ENABLED}, {@link
Publishing#ENABLED_FOR_UPDATES_ONLY} or {@link Publishing#DISABLED}.
*/
@NonNull Publishing getEntityChangePublishing();
@@ -42,7 +42,8 @@ default boolean isPublishingVetoed() {
}
default boolean isPublishingAllowed() {
- return getEntityChangePublishing() == Publishing.ENABLED;
+ return getEntityChangePublishing() == Publishing.ENABLED
+ || getEntityChangePublishing() ==
Publishing.ENABLED_FOR_UPDATES_ONLY;
}
static boolean isExcludedFromPublishing(final @NonNull OneToOneAssociation
property) {
@@ -58,7 +59,7 @@ static boolean isExcludedFromPublishing(final @NonNull
OneToOneAssociation prope
.map(EntityPropertyChangePublishingPolicyFacet::isPublishingAllowed)
.orElse(false);
- //XXX CAUSEWAY-1488, exclude Bob/Clob from property change
publishing unless explicitly allowed
+ //XXX CAUSEWAY-1488, exclude Blob/Clob from property change
publishing unless explicitly allowed
return !isExplictlyAllowed;
}
diff --git
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation.java
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation.java
index dbf4cc19abc..bcba7479eb2 100644
---
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation.java
+++
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/entitychangepublishing/EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation.java
@@ -34,9 +34,9 @@ public static
Optional<EntityPropertyChangePublishingPolicyFacet> create(
return propertyIfAny
.map(Property::entityChangePublishing)
// only install facet if policy is explicit ('enabled' or
'disabled')
- .filter(entityChangePublishing ->
- entityChangePublishing == Publishing.ENABLED
- || entityChangePublishing == Publishing.DISABLED)
+ .filter(entityChangePublishing -> entityChangePublishing ==
Publishing.ENABLED
+ || entityChangePublishing ==
Publishing.ENABLED_FOR_UPDATES_ONLY
+ || entityChangePublishing == Publishing.DISABLED)
.map(entityChangePublishing ->
new
EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation(entityChangePublishing,
holder));
}
diff --git
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java
index 6e284489ccb..a286ff984aa 100644
---
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java
+++
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java
@@ -120,8 +120,7 @@ public static CollectionScenarioBuilder builder(final
Class<?> declaringClass, f
// -- SETUP
- @Getter(onMethod_ = {@Override})
- private MetaModelContext metaModelContext;
+ @Getter(onMethod_ = {@Override}) protected MetaModelContext
metaModelContext;
private MethodRemover_forTesting methodRemover;
diff --git
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
index e6fb9db01d6..deb67cba2de 100644
---
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
+++
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
@@ -24,6 +24,7 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
@@ -39,12 +40,12 @@
import org.apache.causeway.applib.annotation.Bounding;
import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.DomainService;
+import org.apache.causeway.applib.annotation.Publishing;
import org.apache.causeway.applib.id.LogicalType;
import org.apache.causeway.applib.mixins.system.HasInteractionId;
import org.apache.causeway.commons.collections.Can;
import
org.apache.causeway.core.config.metamodel.facets.DomainObjectConfigOptions;
import org.apache.causeway.core.metamodel.facetapi.Facet;
-import
org.apache.causeway.core.metamodel.facets.AbstractTestWithMetaModelContext;
import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract;
import
org.apache.causeway.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
import
org.apache.causeway.core.metamodel.facets.object.domainobject.autocomplete.AutoCompleteFacetForDomainObjectAnnotation;
@@ -74,7 +75,7 @@ protected void tearDown() throws Exception {
facetFactory = null;
}
- class Customer {
+ static class Customer {
}
class SomeHasInteractionId implements HasInteractionId {
@@ -110,7 +111,8 @@ protected void ignoringConfiguration() {
facetFactory = new
DomainObjectAnnotationFacetFactory(getMetaModelContext());
}
- public static class EntityChangePublishing extends
DomainObjectAnnotationFacetFactoryTest {
+ @Nested
+ public class EntityChangePublishing {
@DomainObject(entityChangePublishing =
org.apache.causeway.applib.annotation.Publishing.AS_CONFIGURED)
class CustomerWithDomainObjectAndAuditingSetToAsConfigured {
@@ -124,7 +126,12 @@ class CustomerWithDomainObjectAndAuditingSetToDisabled {
class CustomerWithDomainObjectAndAuditingSetToEnabled {
}
- public static class WhenNotAnnotatedAndDefaultsFromConfiguration
extends EntityChangePublishing {
+ @DomainObject(entityChangePublishing =
Publishing.ENABLED_FOR_UPDATES_ONLY)
+ class
CustomerWithDomainObjectAndEntityChangePublishingSetToEnabledForUpdatesOnly {
+ }
+
+ @Nested
+ public class WhenNotAnnotatedAndDefaultsFromConfiguration {
@Test
void configured_value_set_to_all() {
@@ -158,7 +165,8 @@ void configured_value_set_to_none() {
}
- public static class
WithDomainObjectAnnotationWithAuditingSetToAsConfigured extends
EntityChangePublishing {
+ @Nested
+ public class WithDomainObjectAnnotationWithAuditingSetToAsConfigured {
@Test
public void configured_value_set_to_all() {
@@ -191,7 +199,8 @@ public void configured_value_set_to_none() {
}
- public static class WithDomainObjectAnnotationWithAuditingSetToEnabled
extends EntityChangePublishing {
+ @Nested
+ public class WithDomainObjectAnnotationWithAuditingSetToEnabled {
@Test
public void irrespective_of_configured_value() {
@@ -209,7 +218,31 @@ public void irrespective_of_configured_value() {
}
- public static class
WithDomainObjectAnnotationWithAuditingSetToDisabled extends
EntityChangePublishing {
+ @Nested
+ public class
WithDomainObjectAnnotationWithEntityChangePublishingSetToEnabledForUpdatesOnly {
+
+ @Test
+ public void irrespective_of_configured_value() {
+ allowingEntityChangePublishingToReturn(null);
+
objectScenario(CustomerWithDomainObjectAndEntityChangePublishingSetToEnabledForUpdatesOnly.class,
(processClassContext, facetHolder)->{
+ facetFactory.process(processClassContext);
+
+ final Facet facet =
facetHolder.getFacet(EntityChangePublishingFacet.class);
+ assertNotNull(facet);
+ assertTrue(facet instanceof
EntityChangePublishingFacetForDomainObjectAnnotation);
+
+
assertFalse(EntityChangePublishingFacet.isPublishingEnabledForCreate(facetHolder));
+
assertTrue(EntityChangePublishingFacet.isPublishingEnabledForUpdate(facetHolder));
+
assertFalse(EntityChangePublishingFacet.isPublishingEnabledForDelete(facetHolder));
+
+ assertNoMethodsRemoved();
+ });
+ }
+
+ }
+
+ @Nested
+ public class WithDomainObjectAnnotationWithAuditingSetToDisabled {
@Test
public void irrespective_of_configured_value() {
@@ -226,7 +259,8 @@ public void irrespective_of_configured_value() {
}
}
- public static class AutoComplete extends
DomainObjectAnnotationFacetFactoryTest {
+ @Nested
+ public class AutoComplete {
class CustomerRepository {
public String lookup(final String x) { return null; }
@@ -322,7 +356,8 @@ public void whenNoDomainObjectAnnotation() {
}
- public static class Bounded extends DomainObjectAnnotationFacetFactoryTest
{
+ @Nested
+ public class Bounded {
@DomainObject(bounding = Bounding.BOUNDED)
class CustomerWithDomainObjectAndBoundedSetToTrue {
@@ -384,24 +419,24 @@ public void whenNoDomainObjectAnnotation() {
}
}
- public static class Editing extends DomainObjectAnnotationFacetFactoryTest
{
- class CustomerWithImmutableAnnotation {
- }
+ @DomainObject(editing =
org.apache.causeway.applib.annotation.Editing.AS_CONFIGURED)
+ static class CustomerWithDomainObjectAndEditingSetToAsConfigured {
+ }
- @DomainObject(editing =
org.apache.causeway.applib.annotation.Editing.AS_CONFIGURED)
- class CustomerWithDomainObjectAndEditingSetToAsConfigured {
- }
+ @DomainObject(editing =
org.apache.causeway.applib.annotation.Editing.DISABLED)
+ static class CustomerWithDomainObjectAndEditingSetToDisabled {
+ }
- @DomainObject(editing =
org.apache.causeway.applib.annotation.Editing.DISABLED)
- class CustomerWithDomainObjectAndEditingSetToDisabled {
- }
+ @DomainObject(editing =
org.apache.causeway.applib.annotation.Editing.ENABLED)
+ static class CustomerWithDomainObjectAndEditingSetToEnabled {
+ }
- @DomainObject(editing =
org.apache.causeway.applib.annotation.Editing.ENABLED)
- class CustomerWithDomainObjectAndEditingSetToEnabled {
- }
+ @Nested
+ public class Editing {
- public static class WhenNotAnnotatedAndDefaultsFromConfiguration
extends Editing {
+ @Nested
+ public class WhenNotAnnotatedAndDefaultsFromConfiguration {
@Test
public void configured_value_set_to_true() {
@@ -448,7 +483,8 @@ public void configured_value_set_to_defaults() {
}
}
- public static class
WithDomainObjectAnnotationWithEditingSetToAsConfigured extends Editing {
+ @Nested
+ public class WithDomainObjectAnnotationWithEditingSetToAsConfigured {
@Test
public void configured_value_set_to_true() {
@@ -492,7 +528,8 @@ public void configured_value_set_to_defaults() {
}
}
- public static class WithDomainObjectAnnotationWithEditingSetToEnabled
extends Editing {
+ @Nested
+ public class WithDomainObjectAnnotationWithEditingSetToEnabled {
@Test
public void irrespective_of_configured_value() {
@@ -508,7 +545,8 @@ public void irrespective_of_configured_value() {
}
}
- public static class WithDomainObjectAnnotationWithEditingSetToDisabled
extends Editing {
+ @Nested
+ public class WithDomainObjectAnnotationWithEditingSetToDisabled {
@Test
public void irrespective_of_configured_value() {
@@ -526,16 +564,17 @@ public void irrespective_of_configured_value() {
}
}
- public static class LogicalTypeName extends
DomainObjectAnnotationFacetFactoryTest {
+ @Named("CUS")
+ @DomainObject
+ static class LogicalTypeNameCustomerWithDomainObjectAndObjectTypeSet {
+ }
- @Named("CUS")
- @DomainObject
- class CustomerWithDomainObjectAndObjectTypeSet {
- }
+ @DomainObject
+ static class LogicalTypeNameCustomerWithDomainObjectButNoObjectType {
+ }
- @DomainObject
- class CustomerWithDomainObjectButNoObjectType {
- }
+ @Nested
+ public class LogicalTypeName {
@BeforeEach
public void setUp() {
@@ -544,7 +583,7 @@ public void setUp() {
@Test
public void whenDomainObjectAndObjectTypeSetToTrue() {
-
assertThat(LogicalType.infer(CustomerWithDomainObjectAndObjectTypeSet.class).logicalName(),
+
assertThat(LogicalType.infer(LogicalTypeNameCustomerWithDomainObjectAndObjectTypeSet.class).logicalName(),
is("CUS"));
assertNoMethodsRemoved();
}
@@ -552,7 +591,7 @@ public void whenDomainObjectAndObjectTypeSetToTrue() {
@Test
public void whenDomainObjectAndObjectTypeNotSet() {
- objectScenario(CustomerWithDomainObjectButNoObjectType.class,
(processClassContext, facetHolder)->{
+
objectScenario(LogicalTypeNameCustomerWithDomainObjectButNoObjectType.class,
(processClassContext, facetHolder)->{
facetFactory.process(processClassContext);
final Facet facet = facetHolder.getFacet(AliasedFacet.class);
@@ -577,23 +616,24 @@ public void whenNoDomainObjectAnnotation() {
}
- public static class Nature extends DomainObjectAnnotationFacetFactoryTest {
+ @DomainObject(nature = org.apache.causeway.applib.annotation.Nature.ENTITY)
+ static class CustomerWithDomainObjectAndNatureSetToJdoEntity {
+ }
- @DomainObject(nature =
org.apache.causeway.applib.annotation.Nature.ENTITY)
- class CustomerWithDomainObjectAndNatureSetToJdoEntity {
- }
+ @DomainObject(nature =
org.apache.causeway.applib.annotation.Nature.NOT_SPECIFIED)
+ static class CustomerWithDomainObjectAndNatureSetToNotSpecified {
+ }
- @DomainObject(nature =
org.apache.causeway.applib.annotation.Nature.NOT_SPECIFIED)
- class CustomerWithDomainObjectAndNatureSetToNotSpecified {
- }
+ @DomainObject(nature =
org.apache.causeway.applib.annotation.Nature.VIEW_MODEL)
+ static class CustomerWithDomainObjectAndNatureSetToViewModel {
+ }
- @DomainObject(nature =
org.apache.causeway.applib.annotation.Nature.VIEW_MODEL)
- class CustomerWithDomainObjectAndNatureSetToViewModel {
- }
+ @DomainObject
+ static class CustomerWithDomainObjectButNoNature {
+ }
- @DomainObject
- class CustomerWithDomainObjectButNoNature {
- }
+ @Nested
+ public class Nature {
@BeforeEach
public void setUp() {
@@ -658,18 +698,19 @@ public void whenNoDomainObjectAnnotation() {
}
- public static class Alias extends AbstractTestWithMetaModelContext {
- DomainObjectAnnotationFacetFactory facetFactory;
+ @Named("object.name")
+ @DomainObject(aliased = {"object.name", "object.alias"})
+ static class AliasDomainObjectWithAliases {
+ }
- @Named("object.name")
- @DomainObject(aliased = {"object.name", "object.alias"})
- class DomainObjectWithAliases {
- }
+ @Named("service.name")
+ @DomainService(aliased = {"service.name", "service.alias"})
+ static class AliasDomainServiceWithAliases {
+ }
- @Named("service.name")
- @DomainService(aliased = {"service.name", "service.alias"})
- class DomainServiceWithAliases {
- }
+ @Nested
+ public class Alias {
+ DomainObjectAnnotationFacetFactory facetFactory;
@Test
public void testValidationDomainObjectWithAliasesConfigured() {
@@ -680,7 +721,7 @@ public void
testValidationDomainObjectWithAliasesConfigured() {
facetFactory = new
DomainObjectAnnotationFacetFactory(getMetaModelContext());
((MetaModelContext_forTesting)
getMetaModelContext()).getProgrammingModel();//kicks off the programming model
factory
-
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(DomainObjectWithAliases.class);
+
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(AliasDomainObjectWithAliases.class);
ValidationFailures validationFailures =
getMetaModelContext().getSpecificationLoader().getOrAssessValidationResult();
assertFalse(validationFailures.hasFailures());
}
@@ -694,7 +735,7 @@ public void
testValidationDomainServiceWithAliasesConfigured() {
facetFactory = new
DomainObjectAnnotationFacetFactory(getMetaModelContext());
((MetaModelContext_forTesting)
getMetaModelContext()).getProgrammingModel();//kicks off the programming model
factory
-
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(DomainServiceWithAliases.class);
+
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(AliasDomainServiceWithAliases.class);
ValidationFailures validationFailures =
getMetaModelContext().getSpecificationLoader().getOrAssessValidationResult();
assertFalse(validationFailures.hasFailures());
}
@@ -706,7 +747,7 @@ public void testValidationDomainObjectWithAliasesDefault() {
facetFactory = new
DomainObjectAnnotationFacetFactory(getMetaModelContext());
((MetaModelContext_forTesting)
getMetaModelContext()).getProgrammingModel();//kicks off the programming model
factory
-
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(DomainObjectWithAliases.class);
+
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(AliasDomainObjectWithAliases.class);
ValidationFailures validationFailures =
getMetaModelContext().getSpecificationLoader().getOrAssessValidationResult();
assertTrue(validationFailures.hasFailures());
}
@@ -719,7 +760,7 @@ public void testValidationDomainServiceWithAliasesDefault()
{
facetFactory = new
DomainObjectAnnotationFacetFactory(getMetaModelContext());
((MetaModelContext_forTesting)
getMetaModelContext()).getProgrammingModel();//kicks off the programming model
factory
-
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(DomainServiceWithAliases.class);
+
getMetaModelContext().getSpecificationLoader().specForTypeElseFail(AliasDomainServiceWithAliases.class);
ValidationFailures validationFailures =
getMetaModelContext().getSpecificationLoader().getOrAssessValidationResult();
assertTrue(validationFailures.hasFailures());
}
diff --git
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
index e4a67edb234..17bbf6dab49 100644
---
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
+++
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactoryTest.java
@@ -193,9 +193,8 @@ private void assertHasPropertyDomainEventFacet(
assertEquals(eventTypeOrigin,
domainEventFacet.getEventTypeOrigin());
assertThat(domainEventFacet.getEventType(),
CausewayMatchers.classEqualTo(eventType));
- if(facetedMethod.methodFacade().getName().equals("prop")) {
+ if(facetedMethod.methodFacade().getName().equals("prop"))
return; // skip further checks, when in a mixed-in scenario
- }
// then
var setterFacet =
facetedMethod.getFacet(PropertySetterFacet.class);
@@ -669,7 +668,7 @@ class Customer {
// when
processEntityPropertyChangePublishing(facetFactory,
processMethodContext);
// then
- var changePolicyFacet =
facetedMethod.getFacet(EntityPropertyChangePublishingPolicyFacet.class);
+ var changePolicyFacet =
facetedMethod.lookupFacet(EntityPropertyChangePublishingPolicyFacet.class).orElse(null);
assertNotNull(changePolicyFacet);
assertTrue(changePolicyFacet.isPublishingVetoed());
assertFalse(changePolicyFacet.isPublishingAllowed());
diff --git
a/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/integration/changetracking/EntityChangeTrackerDefault.java
b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/integration/changetracking/EntityChangeTrackerDefault.java
index 42ed58076e4..78f8cc9d4d1 100644
---
a/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/integration/changetracking/EntityChangeTrackerDefault.java
+++
b/persistence/commons/src/main/java/org/apache/causeway/persistence/commons/integration/changetracking/EntityChangeTrackerDefault.java
@@ -39,18 +39,12 @@
import jakarta.inject.Named;
import jakarta.inject.Provider;
-import org.apache.causeway.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
-import org.apache.causeway.core.metamodel.execution.InteractionInternal;
-
-import org.apache.causeway.core.metamodel.services.deadlock.DeadlockRecognizer;
-import org.apache.causeway.schema.chg.v2.ChangesDto;
-import org.apache.causeway.schema.chg.v2.ObjectsDto;
-import org.apache.causeway.schema.common.v2.OidsDto;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.annotation.Qualifier;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.core.Ordered;
-import org.jspecify.annotations.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronization;
@@ -61,6 +55,7 @@
import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.annotation.Programmatic;
import org.apache.causeway.applib.annotation.TransactionScope;
+import org.apache.causeway.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.applib.services.iactn.Interaction;
import org.apache.causeway.applib.services.iactn.InteractionProvider;
@@ -74,10 +69,12 @@
import org.apache.causeway.commons.internal.collections._Sets;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
import org.apache.causeway.core.config.CausewayConfiguration;
+import org.apache.causeway.core.metamodel.execution.InteractionInternal;
import
org.apache.causeway.core.metamodel.facets.object.publish.entitychange.EntityChangePublishingFacet;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.core.metamodel.object.MmEntityUtils;
+import org.apache.causeway.core.metamodel.services.deadlock.DeadlockRecognizer;
import
org.apache.causeway.core.metamodel.services.objectlifecycle.HasEnlistedEntityPropertyChanges;
import
org.apache.causeway.core.metamodel.services.objectlifecycle.PreAndPostValue;
import
org.apache.causeway.core.metamodel.services.objectlifecycle.PropertyChangeRecord;
@@ -88,9 +85,11 @@
import
org.apache.causeway.core.transaction.changetracking.EntityPropertyChangePublisher;
import
org.apache.causeway.core.transaction.changetracking.HasEnlistedEntityChanges;
import
org.apache.causeway.persistence.commons.CausewayModulePersistenceCommons;
+import org.apache.causeway.schema.chg.v2.ChangesDto;
+import org.apache.causeway.schema.chg.v2.ObjectsDto;
+import org.apache.causeway.schema.common.v2.OidsDto;
import lombok.Getter;
-import org.jspecify.annotations.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -305,21 +304,18 @@ private boolean shouldPublish(final PreAndPostValue
preAndPostValue) {
private boolean isEntityExcludedForChangePublishing(final ManagedObject
entity) {
- if (!configuration.isEnabled()) {
+ if (!configuration.isEnabled())
return true;
- }
- if(!EntityChangePublishingFacet.isPublishingEnabled(entity.objSpec()))
{
+ if(!EntityChangePublishingFacet.isPublishingEnabled(entity.objSpec()))
return true; // ignore entities that are not enabled for entity
change publishing
- }
// guard against transient
if(ManagedObjects.bookmark(entity).isEmpty()) return true;
- if(changes.isMemoized()) {
+ if(changes.isMemoized())
throw _Exceptions.illegalState("Cannot enlist additional changes
for auditing, "
+ "since changedObjectPropertiesRef was already prepared
(memoized) for auditing.");
- }
return false;
}
@@ -373,9 +369,8 @@ public Optional<EntityChanges> getEntityChanges(
// a defensive copy of
var changeKindByEnlistedAdapter = new
HashMap<>(this.changeKindByEnlistedAdapter);
- if(changeKindByEnlistedAdapter.isEmpty()) {
+ if(changeKindByEnlistedAdapter.isEmpty())
return Optional.empty();
- }
final Interaction interaction = currentInteraction();
final int numberEntitiesLoaded1 = numberEntitiesLoaded();
@@ -418,9 +413,8 @@ private static ChangesDto newDto(
changeKindByEnlistedEntity.forEach((bookmark, kind)->{
var oidDto = bookmark.toOidDto();
- if(oidDto==null) {
+ if(oidDto==null)
return;
- }
switch(kind) {
case CREATE:
objectsDto.getCreated().getOid().add(oidDto);
@@ -530,9 +524,9 @@ public void enlistCreated(final ManagedObject entity) {
_Xray.enlistCreated(entity, interactionProviderProvider);
- if (isEntityExcludedForChangePublishing(entity)) {
+ if (isEntityExcludedForChangePublishing(entity)
+ ||
!EntityChangePublishingFacet.isPublishingEnabledForCreate(entity.objSpec()))
return;
- }
log.debug("enlist entity's property changes for publishing {}",
entity);
@@ -551,9 +545,9 @@ public void enlistUpdating(
_Xray.enlistUpdating(entity, interactionProviderProvider);
- if (isEntityExcludedForChangePublishing(entity)) {
+ if (isEntityExcludedForChangePublishing(entity)
+ ||
!EntityChangePublishingFacet.isPublishingEnabledForUpdate(entity.objSpec()))
return;
- }
if(log.isDebugEnabled()) {
log.debug("enlist entity's property changes for publishing {}",
entity);
@@ -588,7 +582,9 @@ public void enlistDeleting(final ManagedObject entity) {
_Xray.enlistDeleting(entity, interactionProviderProvider);
- if (isEntityExcludedForChangePublishing(entity)) return;
+ if (isEntityExcludedForChangePublishing(entity)
+ ||
!EntityChangePublishingFacet.isPublishingEnabledForDelete(entity.objSpec()))
+ return;
suppressAutoFlushIfRequired(() -> {
final boolean enlisted = enlistForChangeKindPublishing(entity,
EntityChangeKind.DELETE);