Skip to content

Commit 45c48b6

Browse files
committed
CAUSEWAY-3989: adds ReplayableCommand as a facade
1 parent 1562d7d commit 45c48b6

4 files changed

Lines changed: 144 additions & 15 deletions

File tree

extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/app/CommandLogMenu.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.causeway.applib.annotation.Publishing;
3737
import org.apache.causeway.applib.annotation.RestrictTo;
3838
import org.apache.causeway.applib.annotation.SemanticsOf;
39+
import org.apache.causeway.applib.services.bookmark.BookmarkService;
3940
import org.apache.causeway.applib.services.clock.ClockService;
4041
import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
4142
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
@@ -66,6 +67,7 @@ public class CommandLogMenu {
6667
public static abstract class ActionDomainEvent<T>
6768
extends CausewayModuleExtCommandLogApplib.ActionDomainEvent<T> { }
6869

70+
final BookmarkService bookmarkService;
6971
final CommandLogEntryRepository commandLogEntryRepository;
7072
final ClockService clockService;
7173

extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntryRepositoryAbstract.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,10 @@
3939
import org.apache.causeway.applib.services.command.Command;
4040
import org.apache.causeway.applib.services.factory.FactoryService;
4141
import org.apache.causeway.applib.services.repository.RepositoryService;
42-
import org.apache.causeway.applib.util.schema.CommandDtoUtils;
4342
import org.apache.causeway.commons.internal.base._Casts;
4443
import org.apache.causeway.core.config.environment.CausewaySystemEnvironment;
4544
import org.apache.causeway.schema.cmd.v2.CommandDto;
4645
import org.apache.causeway.schema.cmd.v2.CommandsDto;
47-
import org.apache.causeway.schema.cmd.v2.MapDto;
48-
import org.apache.causeway.schema.common.v2.InteractionType;
4946

5047
/**
5148
* Provides supporting functionality for querying {@link CommandLogEntry command log entry} entities.
@@ -350,18 +347,20 @@ public List<CommandLogEntry> findNotYetReplayed() {
350347
@Override
351348
public C saveForReplay(final CommandDto commandToReplay) {
352349

353-
if(commandToReplay.getMember().getInteractionType() == InteractionType.ACTION_INVOCATION) {
354-
final MapDto userData = commandToReplay.getUserData();
355-
if (userData == null )
356-
throw new IllegalStateException(String.format(
357-
"Can only persist action DTOs with additional userData; got: \n%s",
358-
CommandDtoUtils.dtoMapper().toString(commandToReplay)));
359-
}
350+
//TODO why?
351+
// if(commandToReplay.getMember().getInteractionType() == InteractionType.ACTION_INVOCATION) {
352+
// final MapDto userData = commandToReplay.getUserData();
353+
// if (userData == null )
354+
// throw new IllegalStateException(String.format(
355+
// "Can only persist action DTOs with additional userData; got: \n%s",
356+
// CommandDtoUtils.dtoMapper().toString(commandToReplay)));
357+
// }
360358

361359
final C entity = factoryService.detachedEntity(commandLogEntryClass);
362360
entity.init(commandToReplay, ReplayState.PENDING, 0);
363361
entity.setParentInteractionId(null); // n/a for replay
364362
entity.setExecuteIn(null); // to be specified later depending on user action
363+
365364
persist(entity);
366365

367366
return entity;

extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/CommandReplayManager.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,43 @@
2020

2121
import java.util.List;
2222

23+
import jakarta.inject.Inject;
2324
import jakarta.inject.Named;
2425

2526
import org.apache.causeway.applib.ViewModel;
2627
import org.apache.causeway.applib.annotation.Action;
2728
import org.apache.causeway.applib.annotation.ActionLayout;
29+
import org.apache.causeway.applib.annotation.Collection;
30+
import org.apache.causeway.applib.annotation.DomainObject;
2831
import org.apache.causeway.applib.annotation.DomainObjectLayout;
32+
import org.apache.causeway.applib.annotation.Introspection;
2933
import org.apache.causeway.applib.annotation.ObjectSupport;
3034
import org.apache.causeway.applib.annotation.Parameter;
35+
import org.apache.causeway.applib.services.bookmark.BookmarkService;
3136
import org.apache.causeway.applib.util.schema.CommandDtoUtils;
3237
import org.apache.causeway.applib.value.Blob;
3338
import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType;
3439
import org.apache.causeway.commons.io.JsonUtils;
3540
import org.apache.causeway.commons.io.YamlUtils;
3641
import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
42+
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
3743
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntryRepository;
3844
import org.apache.causeway.schema.cmd.v2.CommandDto;
3945

46+
@DomainObject(introspection = Introspection.ANNOTATION_REQUIRED)
4047
@DomainObjectLayout(cssClassFa = "solid circle-play")
4148
@Named(CommandReplayManager.LOGICAL_TYPE_NAME)
42-
public class CommandReplayManager implements ViewModel {
49+
public record CommandReplayManager(
50+
BookmarkService bookmarkService,
51+
CommandLogEntryRepository commandLogEntryRepository) implements ViewModel {
4352

4453
public static final String LOGICAL_TYPE_NAME = CausewayModuleExtCommandLogApplib.NAMESPACE + ".CommandReplayManager";
4554

46-
private final CommandLogEntryRepository commandLogEntryRepository;
47-
48-
public CommandReplayManager(final String memento, final CommandLogEntryRepository commandLogEntryRepository) {
49-
this.commandLogEntryRepository = commandLogEntryRepository;
55+
@Inject
56+
public CommandReplayManager(final String memento,
57+
final BookmarkService bookmarkService,
58+
final CommandLogEntryRepository commandLogEntryRepository) {
59+
this(bookmarkService, commandLogEntryRepository);
5060
}
5161

5262
@ObjectSupport public String title() {
@@ -70,6 +80,17 @@ public String importCommands(
7080
return yaml;
7181
}
7282

83+
@Collection
84+
public List<CommandLogEntry> getNotYetReplayedRaw() {
85+
return commandLogEntryRepository.findNotYetReplayed();
86+
}
87+
88+
@Collection
89+
public List<ReplayableCommand> getNotYetReplayed() {
90+
return commandLogEntryRepository.findNotYetReplayed().stream()
91+
.map(entry->new ReplayableCommand(bookmarkService.bookmarkFor(entry).get().identifier(), bookmarkService, commandLogEntryRepository))
92+
.toList();
93+
}
7394

7495
@Override
7596
public String viewModelMemento() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.causeway.extensions.commandlog.applib.dom.replay;
20+
21+
import java.util.Optional;
22+
import java.util.UUID;
23+
24+
import jakarta.inject.Inject;
25+
import jakarta.inject.Named;
26+
27+
import org.apache.causeway.applib.ViewModel;
28+
import org.apache.causeway.applib.annotation.DomainObject;
29+
import org.apache.causeway.applib.annotation.DomainObjectLayout;
30+
import org.apache.causeway.applib.annotation.Introspection;
31+
import org.apache.causeway.applib.annotation.ObjectSupport;
32+
import org.apache.causeway.applib.annotation.Property;
33+
import org.apache.causeway.applib.services.bookmark.Bookmark;
34+
import org.apache.causeway.applib.services.bookmark.BookmarkService;
35+
import org.apache.causeway.commons.internal.base._StableValue;
36+
import org.apache.causeway.commons.internal.exceptions._Exceptions;
37+
import org.apache.causeway.extensions.commandlog.applib.CausewayModuleExtCommandLogApplib;
38+
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry;
39+
import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntryRepository;
40+
import org.apache.causeway.extensions.commandlog.applib.dom.ReplayState;
41+
import org.apache.causeway.schema.cmd.v2.CommandDto;
42+
43+
/**
44+
* Viewmodel that wraps a {@link CommandLogEntry}.
45+
*/
46+
@DomainObject(introspection = Introspection.ANNOTATION_REQUIRED)
47+
@DomainObjectLayout(cssClassFa = "terminal")
48+
@Named(ReplayableCommand.LOGICAL_TYPE_NAME)
49+
public record ReplayableCommand(
50+
String commandLogEntryId,
51+
BookmarkService bookmarkService,
52+
CommandLogEntryRepository commandLogEntryRepository,
53+
_StableValue<CommandRecord> recordRef) implements ViewModel {
54+
55+
public static final String LOGICAL_TYPE_NAME = CausewayModuleExtCommandLogApplib.NAMESPACE + ".ReplayableCommand";
56+
57+
// decouple from the underlying entity
58+
record CommandRecord(
59+
CommandDto commandDto,
60+
ReplayState replayState) {
61+
}
62+
63+
@Inject
64+
public ReplayableCommand(
65+
final String memento,
66+
final BookmarkService bookmarkService,
67+
final CommandLogEntryRepository commandLogEntryRepository) {
68+
this(memento, bookmarkService, commandLogEntryRepository, new _StableValue<>());
69+
}
70+
71+
@ObjectSupport public String title() {
72+
return "Replayable Command";
73+
}
74+
75+
@Property
76+
public UUID getInteractionId() {
77+
return commandRecord()
78+
.map(CommandRecord::commandDto)
79+
.map(CommandDto::getInteractionId)
80+
.map(UUID::fromString)
81+
.orElse(null);
82+
}
83+
84+
@Override
85+
public String viewModelMemento() {
86+
return commandLogEntryId;
87+
}
88+
89+
// -- HELPER
90+
91+
private Optional<CommandRecord> commandRecord() {
92+
return commandLogEntry()
93+
.map(commandLogEntry->new CommandRecord(commandLogEntry.getCommandDto(), commandLogEntry.getReplayState()));
94+
}
95+
96+
private Optional<CommandLogEntry> commandLogEntry() {
97+
return bookmarkService.lookup(commandLogEntryBookmark(), CommandLogEntry.class);
98+
}
99+
100+
private Bookmark commandLogEntryBookmark() {
101+
return bookmarkService.bookmarkFor(CommandLogEntry.class, commandLogEntryId)
102+
.orElseThrow(()->_Exceptions.unrecoverable(
103+
"framework error: cannot create bookmark for CommandLogEntry using id '%s'",
104+
commandLogEntryId));
105+
}
106+
107+
}

0 commit comments

Comments
 (0)