You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2026/06/19 06:47:38 UTC

(causeway) 07/11: CAUSEWAY-4039: renames ReplayableCommand#isReplayable to isDoOp

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

danhaywood pushed a commit to branch CAUSEWAY-4039
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit eb0d2fecead1a6063dbf1d3aa44ea8551497ebd5
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Fri Jun 19 06:51:20 2026 +0100

    CAUSEWAY-4039: renames ReplayableCommand#isReplayable to isDoOp
---
 .../applib/dom/replay/CommandManagerAbstract.java  |  9 +++
 .../applib/dom/replay/CommandManagerExport.java    | 22 ++----
 .../applib/dom/replay/CommandManagerReplay.java    | 21 ++----
 .../applib/dom/replay/ReplayableCommand.java       | 61 +++++++++++++++--
 .../dom/replay/ReplayableCommandEligibility.java   | 78 ----------------------
 ...ityTest.java => ReplayableCommandUtilTest.java} | 14 ++--
 6 files changed, 82 insertions(+), 123 deletions(-)

diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerAbstract.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerAbstract.java
index 228185e605e..bbc7bcd2212 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerAbstract.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerAbstract.java
@@ -26,6 +26,7 @@
 import java.time.Instant;
 
 import org.apache.causeway.applib.ViewModel;
+import org.apache.causeway.applib.annotation.ObjectSupport;
 import org.apache.causeway.applib.annotation.Programmatic;
 import org.apache.causeway.applib.annotation.Property;
 import org.apache.causeway.applib.annotation.PropertyLayout;
@@ -60,6 +61,14 @@ ReplayContext replayContext() {
     }
 
 
+    @ObjectSupport
+    public String title() {
+        return this instanceof CommandManagerExport
+                ? "Command Export Manager"
+                : "Command Replay Manager";
+    }
+
+
     // -- VM STATE
 
     @Override
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerExport.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerExport.java
index 141769b17fc..c46a5b56b57 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerExport.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerExport.java
@@ -29,16 +29,12 @@
 import javax.inject.Inject;
 import javax.inject.Named;
 
-import org.apache.causeway.applib.ViewModel;
 import org.apache.causeway.applib.annotation.Collection;
 import org.apache.causeway.applib.annotation.CollectionLayout;
 import org.apache.causeway.applib.annotation.DomainObject;
 import org.apache.causeway.applib.annotation.DomainObjectLayout;
 import org.apache.causeway.applib.annotation.Introspection;
-import org.apache.causeway.applib.annotation.ObjectSupport;
 import org.apache.causeway.applib.annotation.Programmatic;
-import org.apache.causeway.applib.annotation.Property;
-import org.apache.causeway.applib.annotation.PropertyLayout;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.applib.services.scratchpad.Scratchpad;
 import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
@@ -47,8 +43,6 @@
 import org.apache.causeway.extensions.commandlog.applib.dom.ReplayState;
 import org.apache.causeway.extensions.commandlog.applib.spi.CommandReplayReferenceDataService;
 
-import lombok.Getter;
-
 @DomainObject(introspection = Introspection.ANNOTATION_REQUIRED)
 @DomainObjectLayout(cssClassFa = "solid share-from-square")
 @Named(CommandManagerExport.LOGICAL_TYPE_NAME)
@@ -76,10 +70,6 @@ public CommandManagerExport(
         super(state, replayContext);
     }
 
-    @ObjectSupport public String title() {
-        return "Command Export Manager";
-    }
-
     @Override
     @Programmatic
     public CommandManagerExport withBaseline(final Timestamp baseline) {
@@ -101,7 +91,7 @@ public CommandManagerExport withLimit(final int limit) {
     public List<ReplayableCommand> getCommands() {
         putCurrentExportManagerOnScratchpad();
         return activeCommandLogEntries().stream()
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .map(this::replayableCommandInExportManagerContext)
                 .collect(Collectors.toList());
     }
@@ -114,7 +104,7 @@ public List<ReplayableCommand> getCommands() {
     public List<ReplayableCommand> getExcludedCommands() {
         return commandLogEntryRepository().findForegroundSinceTimestamp(baseline, limit).stream()
                 .filter(CommandManagerExport::isExcludedCommand)
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .map(entry -> new ReplayableCommand(
                         entry.getInteractionId(),
                         replayContext))
@@ -124,7 +114,7 @@ public List<ReplayableCommand> getExcludedCommands() {
     @Programmatic
     public List<ReplayableCommand> getCommandsPrevious() {
         return commandLogEntryRepository().findForegroundBeforeTimestamp(baseline, limit).stream()
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .map(entry -> new ReplayableCommand(
                         entry.getInteractionId(),
                         replayContext))
@@ -210,12 +200,12 @@ private boolean isExportRoot(final Bookmark bookmark) {
     List<CommandLogEntry> activeCommandLogEntries() {
         return commandLogEntryRepository().findForegroundSinceTimestamp(baseline, limit).stream()
                 .filter(CommandManagerExport::isActiveCommand)
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .collect(Collectors.toList());
     }
 
-    private boolean isReplayable(final CommandLogEntry entry) {
-        return ReplayableCommandEligibility.isReplayable(entry, replayContext.specificationLoader());
+    private boolean isDoOp(final CommandLogEntry entry) {
+        return ReplayableCommand.Util.isDoOp(entry, replayContext.specificationLoader());
     }
 
     private ReplayableCommand replayableCommandInExportManagerContext(final CommandLogEntry entry) {
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerReplay.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerReplay.java
index b330f65d72a..2238ecfbc55 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerReplay.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandManagerReplay.java
@@ -18,8 +18,6 @@
  */
 package org.apache.causeway.extensions.commandlog.applib.dom.replay;
 
-import static org.apache.causeway.extensions.commandlog.applib.dom.replay.TimestampMarshallUtil.fromString;
-
 import java.sql.Timestamp;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -28,25 +26,18 @@
 import javax.inject.Inject;
 import javax.inject.Named;
 
-import org.apache.causeway.applib.ViewModel;
 import org.apache.causeway.applib.annotation.Collection;
 import org.apache.causeway.applib.annotation.CollectionLayout;
 import org.apache.causeway.applib.annotation.DomainObject;
 import org.apache.causeway.applib.annotation.DomainObjectLayout;
 import org.apache.causeway.applib.annotation.Introspection;
-import org.apache.causeway.applib.annotation.ObjectSupport;
 import org.apache.causeway.applib.annotation.Programmatic;
-import org.apache.causeway.applib.annotation.Property;
-import org.apache.causeway.applib.annotation.PropertyLayout;
-import org.apache.causeway.applib.services.command.CommandRecordingSuppressed;
 import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
 import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
 import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntryRepository;
 
 import org.jspecify.annotations.NonNull;
 
-import lombok.Getter;
-
 @DomainObject(introspection = Introspection.ANNOTATION_REQUIRED)
 @DomainObjectLayout(cssClassFa = "solid circle-play")
 @Named(CommandManagerReplay.LOGICAL_TYPE_NAME)
@@ -72,10 +63,6 @@ public CommandManagerReplay(
         super(state, replayContext);
     }
 
-    @ObjectSupport public String title() {
-        return "Command Replay Manager";
-    }
-
 
     @Override
     @Programmatic
@@ -103,7 +90,7 @@ public List<ReplayableCommand> getPendingOrFailed() {
 
     @NonNull Stream<ReplayableCommand> streamPendingOrFailed() {
         return commandLogEntryRepository().findForegroundSinceTimestampAndWithReplayPendingOrFailed(baseline).stream()
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .map(entry -> new ReplayableCommand(
                         entry.getInteractionId(),
                         replayContext));
@@ -123,7 +110,7 @@ long sizePendingOrFailed() {
     )
     public List<ReplayableCommand> getSucceededOrExcluded() {
         return commandLogEntryRepository().findSinceAndWithReplayOkOrExcluded(baseline).stream()
-            .filter(this::isReplayable)
+            .filter(this::isDoOp)
             .map(entry->new ReplayableCommand(
                     entry.getInteractionId(),
                     replayContext))
@@ -132,8 +119,8 @@ public List<ReplayableCommand> getSucceededOrExcluded() {
 
 
     // -- HELPER
-    private boolean isReplayable(final CommandLogEntry entry) {
-        return ReplayableCommandEligibility.isReplayable(entry, replayContext.specificationLoader());
+    private boolean isDoOp(final CommandLogEntry entry) {
+        return ReplayableCommand.Util.isDoOp(entry, replayContext.specificationLoader());
     }
 
     private CommandLogEntryRepository commandLogEntryRepository() {
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
index d11d9a376fb..f26ba5ffe35 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
@@ -31,6 +31,7 @@
 import javax.inject.Inject;
 import javax.inject.Named;
 
+import org.apache.causeway.applib.Identifier;
 import org.apache.causeway.applib.ViewModel;
 import org.apache.causeway.applib.annotation.Collection;
 import org.apache.causeway.applib.annotation.CollectionLayout;
@@ -42,6 +43,7 @@
 import org.apache.causeway.applib.annotation.Programmatic;
 import org.apache.causeway.applib.annotation.Property;
 import org.apache.causeway.applib.annotation.PropertyLayout;
+import org.apache.causeway.applib.annotation.SemanticsOf;
 import org.apache.causeway.applib.annotation.Where;
 import org.apache.causeway.applib.jaxb.JavaTimeXMLGregorianCalendarMarshalling;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
@@ -56,6 +58,9 @@
 import org.apache.causeway.commons.io.JsonUtils;
 import org.apache.causeway.commons.io.TextUtils;
 import org.apache.causeway.commons.io.YamlUtils;
+import org.apache.causeway.core.metamodel.facets.actions.action.invocation.IdentifierUtil;
+import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
+import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
 import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
 import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
 import org.apache.causeway.extensions.commandlog.applib.dom.ReplayState;
@@ -76,6 +81,7 @@
 
 import lombok.Value;
 import lombok.experimental.Accessors;
+import lombok.experimental.UtilityClass;
 import lombok.extern.log4j.Log4j2;
 
 /**
@@ -662,7 +668,7 @@ private Optional<CommandLogEntry> previousCommandLogEntry(final Timestamp timest
         return replayContext.commandLogEntryRepository()
                 .findForegroundBeforeTimestamp(timestamp, null)
                 .stream()
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .findFirst();
     }
 
@@ -671,12 +677,12 @@ private Optional<CommandLogEntry> nextCommandLogEntry(final Timestamp timestamp)
                 .findForegroundSinceTimestamp(timestamp, null)
                 .stream()
                 .filter(entry -> !interactionId.equals(entry.getInteractionId()))
-                .filter(this::isReplayable)
+                .filter(this::isDoOp)
                 .findFirst();
     }
 
-    private boolean isReplayable(final CommandLogEntry entry) {
-        return ReplayableCommandEligibility.isReplayable(entry, replayContext.specificationLoader());
+    private boolean isDoOp(final CommandLogEntry entry) {
+        return Util.isDoOp(entry, replayContext.specificationLoader());
     }
 
     // -- HELPER
@@ -865,4 +871,51 @@ private void notifyReplayResult(
     }
 
     @Inject BookmarkService bookmarkService;
+
+    @UtilityClass
+    static class Util {
+
+        boolean isDoOp(
+                final CommandLogEntry entry,
+                final SpecificationLoader specificationLoader) {
+            if (entry == null) {
+                return false;
+            }
+            if (!isSafeAction(entry, specificationLoader)) {
+                return true;
+            }
+            return entry.getResult() != null;
+        }
+
+        private boolean isSafeAction(
+                final CommandLogEntry entry,
+                final SpecificationLoader specificationLoader) {
+            if (specificationLoader == null
+                    || entry.getCommandDto() == null
+                    || !(entry.getCommandDto().getMember() instanceof ActionDto)) {
+                return false;
+            }
+            return Optional.ofNullable(entry.getLogicalMemberIdentifier())
+                    .flatMap(logicalMemberIdentifier -> safeActionSemantics(specificationLoader, logicalMemberIdentifier))
+                    .orElse(false);
+        }
+
+        private Optional<Boolean> safeActionSemantics(
+                final SpecificationLoader specificationLoader,
+                final String logicalMemberIdentifier) {
+            try {
+                final var identifier = IdentifierUtil.memberIdentifierFor(
+                        specificationLoader,
+                        Identifier.Type.ACTION,
+                        logicalMemberIdentifier);
+                return specificationLoader.loadFeature(identifier)
+                        .filter(ObjectAction.class::isInstance)
+                        .map(ObjectAction.class::cast)
+                        .map(ObjectAction::getSemantics)
+                        .map(SemanticsOf::isSafeInNature);
+            } catch (final RuntimeException ex) {
+                return Optional.empty();
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandEligibility.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandEligibility.java
deleted file mode 100644
index ddd75639ea0..00000000000
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandEligibility.java
+++ /dev/null
@@ -1,78 +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.causeway.extensions.commandlog.applib.dom.replay;
-
-import java.util.Optional;
-
-import org.apache.causeway.applib.Identifier;
-import org.apache.causeway.applib.annotation.SemanticsOf;
-import org.apache.causeway.core.metamodel.facets.actions.action.invocation.IdentifierUtil;
-import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
-import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
-import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
-import org.apache.causeway.schema.cmd.v2.ActionDto;
-
-import lombok.experimental.UtilityClass;
-
-@UtilityClass
-class ReplayableCommandEligibility {
-
-    boolean isReplayable(
-            final CommandLogEntry entry,
-            final SpecificationLoader specificationLoader) {
-        if (entry == null) {
-            return false;
-        }
-        if (!isSafeAction(entry, specificationLoader)) {
-            return true;
-        }
-        return entry.getResult() != null;
-    }
-
-    private boolean isSafeAction(
-            final CommandLogEntry entry,
-            final SpecificationLoader specificationLoader) {
-        if (specificationLoader == null
-                || entry.getCommandDto() == null
-                || !(entry.getCommandDto().getMember() instanceof ActionDto)) {
-            return false;
-        }
-        return Optional.ofNullable(entry.getLogicalMemberIdentifier())
-                .flatMap(logicalMemberIdentifier -> safeActionSemantics(specificationLoader, logicalMemberIdentifier))
-                .orElse(false);
-    }
-
-    private Optional<Boolean> safeActionSemantics(
-            final SpecificationLoader specificationLoader,
-            final String logicalMemberIdentifier) {
-        try {
-            final var identifier = IdentifierUtil.memberIdentifierFor(
-                    specificationLoader,
-                    Identifier.Type.ACTION,
-                    logicalMemberIdentifier);
-            return specificationLoader.loadFeature(identifier)
-                    .filter(ObjectAction.class::isInstance)
-                    .map(ObjectAction.class::cast)
-                    .map(ObjectAction::getSemantics)
-                    .map(SemanticsOf::isSafeInNature);
-        } catch (final RuntimeException ex) {
-            return Optional.empty();
-        }
-    }
-}
diff --git a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandEligibilityTest.java b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandUtilTest.java
similarity index 88%
rename from extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandEligibilityTest.java
rename to extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandUtilTest.java
index 6f0dbdf7999..075da389593 100644
--- a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandEligibilityTest.java
+++ b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandUtilTest.java
@@ -31,19 +31,17 @@
 
 import org.apache.causeway.applib.Identifier;
 import org.apache.causeway.applib.annotation.SemanticsOf;
-import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
 import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
 import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
-import org.apache.causeway.extensions.commandlog.applib.dom.ReplayState;
 import org.apache.causeway.schema.cmd.v2.ActionDto;
 import org.apache.causeway.schema.cmd.v2.CommandDto;
 import org.apache.causeway.schema.cmd.v2.PropertyDto;
 import org.apache.causeway.schema.common.v2.InteractionType;
 
-class ReplayableCommandEligibilityTest {
+class ReplayableCommandUtilTest {
 
     private static final Bookmark RESULT = Bookmark.forLogicalTypeNameAndIdentifier("demo.Customer", "1");
 
@@ -51,7 +49,7 @@ class ReplayableCommandEligibilityTest {
     void state_changing_property_command_remains_replayable_without_result() {
         final var entry = propertyEntry(null);
 
-        final var replayable = ReplayableCommandEligibility.isReplayable(entry, safeActionSpecificationLoader());
+        final var replayable = ReplayableCommand.Util.isDoOp(entry, safeActionSpecificationLoader());
 
         assertThat(replayable).isTrue();
     }
@@ -60,7 +58,7 @@ void state_changing_property_command_remains_replayable_without_result() {
     void safe_action_with_single_result_is_replayable() {
         final var entry = actionEntry(RESULT);
 
-        final var replayable = ReplayableCommandEligibility.isReplayable(entry, safeActionSpecificationLoader());
+        final var replayable = ReplayableCommand.Util.isDoOp(entry, safeActionSpecificationLoader());
 
         assertThat(replayable).isTrue();
     }
@@ -69,7 +67,7 @@ void safe_action_with_single_result_is_replayable() {
     void safe_action_without_result_is_not_replayable_and_is_not_mutated() {
         final var entry = actionEntry(null);
 
-        final var replayable = ReplayableCommandEligibility.isReplayable(entry, safeActionSpecificationLoader());
+        final var replayable = ReplayableCommand.Util.isDoOp(entry, safeActionSpecificationLoader());
 
         assertThat(replayable).isFalse();
         verify(entry, never()).setReplayState(any());
@@ -80,7 +78,7 @@ void safe_action_without_result_is_not_replayable_and_is_not_mutated() {
     void non_safe_action_without_result_remains_replayable() {
         final var entry = actionEntry(null);
 
-        final var replayable = ReplayableCommandEligibility.isReplayable(entry, nonSafeActionSpecificationLoader());
+        final var replayable = ReplayableCommand.Util.isDoOp(entry, nonSafeActionSpecificationLoader());
 
         assertThat(replayable).isTrue();
     }
@@ -90,7 +88,7 @@ void unresolved_action_semantics_defaults_to_replayable() {
         final var entry = actionEntry(null);
         final var specificationLoader = mock(SpecificationLoader.class);
 
-        final var replayable = ReplayableCommandEligibility.isReplayable(entry, specificationLoader);
+        final var replayable = ReplayableCommand.Util.isDoOp(entry, specificationLoader);
 
         assertThat(replayable).isTrue();
     }