Добавил возможность возвращать пользователя назад в сценарии по названию юнита

This commit is contained in:
Struchkov Mark 2022-07-13 20:39:23 +03:00
parent 996194264e
commit 29145fe093
12 changed files with 117 additions and 65 deletions

View File

@ -6,7 +6,7 @@
<parent>
<groupId>dev.struchkov.godfather</groupId>
<artifactId>godfather-bot</artifactId>
<version>0.0.9</version>
<version>0.0.10</version>
</parent>
<artifactId>bot-context</artifactId>

View File

@ -21,6 +21,11 @@ public class RollBackCmd extends MainUnit {
*/
private final int countBack;
/**
* Имя юнита, на который нужно вернуть пользователя.
*/
private final String rollbackUnitName;
private RollBackCmd(Builder builder) {
super(
builder.name,
@ -35,10 +40,7 @@ public class RollBackCmd extends MainUnit {
TypeUnit.BACK_CMD
);
this.countBack = builder.countBack;
}
public int getCountBack() {
return countBack;
this.rollbackUnitName = builder.rollbackUnitName;
}
public static RollBackCmd.Builder builder() {
@ -53,76 +55,90 @@ public class RollBackCmd extends MainUnit {
return RollBackCmd.builder().countBack(1).build();
}
public int getCountBack() {
return countBack;
}
public String getRollbackUnitName() {
return rollbackUnitName;
}
public static final class Builder {
private final Set<KeyWord> keyWords = new HashSet<>();
private String name;
private Set<KeyWord> keyWords = new HashSet<>();
private String phrase;
private Pattern pattern;
private Integer matchThreshold;
private Integer priority;
private UnitActiveType activeType = UnitActiveType.DEFAULT;
private int countBack;
private String rollbackUnitName;
private Builder() {
}
public RollBackCmd.Builder name(String name) {
public Builder name(String name) {
this.name = name;
return this;
}
public RollBackCmd.Builder keyWords(Set<KeyWord> val) {
public Builder keyWords(Set<KeyWord> val) {
keyWords.addAll(val);
return this;
}
public RollBackCmd.Builder keyWord(KeyWord val) {
public Builder keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public RollBackCmd.Builder stringKeyWords(Set<String> val) {
public Builder stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this;
}
public RollBackCmd.Builder keyWord(String val) {
public Builder keyWord(String val) {
keyWords.add(KeyWord.of(val));
return this;
}
public RollBackCmd.Builder phrase(String val) {
public Builder phrase(String val) {
phrase = val;
return this;
}
public RollBackCmd.Builder pattern(Pattern val) {
public Builder pattern(Pattern val) {
pattern = val;
return this;
}
public RollBackCmd.Builder matchThreshold(Integer val) {
public Builder matchThreshold(Integer val) {
matchThreshold = val;
return this;
}
public RollBackCmd.Builder priority(Integer val) {
public Builder priority(Integer val) {
priority = val;
return this;
}
public RollBackCmd.Builder activeType(UnitActiveType val) {
public Builder activeType(UnitActiveType val) {
activeType = val;
return this;
}
public RollBackCmd.Builder countBack(int val) {
public Builder countBack(int val) {
countBack = val + 1;
return this;
}
public Builder rollbackUnitName(String val) {
rollbackUnitName = val;
return this;
}
public RollBackCmd build() {
if (countBack < 2) {
if (rollbackUnitName == null && countBack < 2) {
throw new UnitConfigException("Ошибка конфигурирования юнита {0}: Количество юнитов для отката не должно быть меньше 1.", name);
}
return new RollBackCmd(this);

View File

@ -0,0 +1,18 @@
package dev.struchkov.godfather.context.exception;
import java.util.function.Supplier;
/**
* Ошибки связанные с юнитом RollBackCmd
*/
public class RollBackException extends AppBotException {
public RollBackException(String message) {
super(message);
}
public static Supplier<RollBackException> rollBackException(String message) {
return () -> new RollBackException(message);
}
}

View File

@ -11,6 +11,8 @@ public interface StorylineRepository {
Optional<StorylineHistory> findByCountLast(long personId, int countUnitsToBack);
Optional<StorylineHistory> findByCountLast(long personId, String unitName);
void cleanHistoryByPersonId(@NotNull Long personId);
}

View File

@ -35,6 +35,21 @@ public class StorylineMapRepository implements StorylineRepository {
return Optional.empty();
}
@Override
public Optional<StorylineHistory> findByCountLast(long personId, String unitName) {
if (map.containsKey(personId)) {
final Stack<StorylineHistory> stack = map.get(personId);
StorylineHistory storylineHistory = null;
while (!stack.isEmpty()) {
storylineHistory = stack.pop();
if (unitName.equals(storylineHistory.getUnitName())) {
return Optional.of(storylineHistory);
}
}
}
return Optional.empty();
}
@Override
public void cleanHistoryByPersonId(@NotNull Long personId) {
if (map.containsKey(personId)) {

View File

@ -20,13 +20,12 @@ public interface StorylineService<T extends Message> {
Optional<StorylineHistory> replaceUserToBack(long personId, int countUnitsToBack);
Optional<StorylineHistory> replaceUserToBack(long personId, String unitName);
Optional<MainUnit> getDefaultUnit();
/**
* Ленивая (поздняя) связка юнитов между собой. Осуществляется уже после создания сценария. С помощью данного подхода можно реализовать циклические зависимости юнитов. Либо можно использовать {@link dev.struchkov.godfather.context.domain.unit.cmd.TeleportCmd}
*
* @param firstName
* @param secondName
*/
void lazyLink(String firstName, String secondName);

View File

@ -6,7 +6,7 @@
<parent>
<groupId>dev.struchkov.godfather</groupId>
<artifactId>godfather-bot</artifactId>
<version>0.0.9</version>
<version>0.0.10</version>
</parent>
<artifactId>bot-core</artifactId>

View File

@ -32,12 +32,10 @@ import java.util.stream.Collectors;
public class GeneralAutoResponder<T extends Message> {
private final PersonSettingService personSettingService;
private ErrorHandler errorHandler;
private final StorylineService<T> storyLineService;
protected Map<String, ActionUnit<? extends MainUnit, ? extends Message>> actionUnitMap = new HashMap<>();
protected List<Modifiable<T>> modifiable;
private ErrorHandler errorHandler;
protected GeneralAutoResponder(
Sending sending,

View File

@ -81,6 +81,11 @@ public class StorylineMailService implements StorylineService<Mail> {
return storylineRepository.findByCountLast(personId, countUnitsToBack);
}
@Override
public Optional<StorylineHistory> replaceUserToBack(long personId, String unitName) {
return storylineRepository.findByCountLast(personId, unitName);
}
@Override
public Optional<MainUnit> getDefaultUnit() {
return storyLine.getDefaultUnit();

View File

@ -1,38 +0,0 @@
package dev.struchkov.godfather.core.service.action.cmd;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.cmd.RollBackCmd;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.service.StorylineService;
import dev.struchkov.godfather.core.service.action.ActionUnit;
import java.util.Optional;
public class BackCmdAction<T extends Message> implements ActionUnit<RollBackCmd, T> {
private final StorylineService<T> storyLineService;
public BackCmdAction(StorylineService<T> storyLineService) {
this.storyLineService = storyLineService;
}
@Override
public UnitRequest<MainUnit, T> action(UnitRequest<RollBackCmd, T> unitRequest) {
final RollBackCmd unit = unitRequest.getUnit();
final T message = unitRequest.getMessage();
final int countToBack = unit.getCountBack();
final Optional<StorylineHistory> optHistory = storyLineService.replaceUserToBack(message.getPersonId(), countToBack);
if (optHistory.isPresent()) {
final StorylineHistory history = optHistory.get();
final String unitName = history.getUnitName();
final MainUnit nextUnit = storyLineService.getUnitByName(unitName).orElse(unit);
final T oldMessage = (T) history.getMessage();
return UnitRequest.of(nextUnit, oldMessage);
}
return UnitRequest.of(unit, message);
}
}

View File

@ -0,0 +1,37 @@
package dev.struchkov.godfather.core.service.action.cmd;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.domain.unit.cmd.RollBackCmd;
import dev.struchkov.godfather.context.service.StorylineService;
import dev.struchkov.godfather.core.service.action.ActionUnit;
import static dev.struchkov.godfather.context.exception.RollBackException.rollBackException;
public class RollBackCmdAction<T extends Message> implements ActionUnit<RollBackCmd, T> {
private final StorylineService<T> storyLineService;
public RollBackCmdAction(StorylineService<T> storyLineService) {
this.storyLineService = storyLineService;
}
@Override
public UnitRequest<MainUnit, T> action(UnitRequest<RollBackCmd, T> unitRequest) {
final RollBackCmd unit = unitRequest.getUnit();
final T message = unitRequest.getMessage();
final int countToBack = unit.getCountBack();
final String rollbackUnitName = unit.getRollbackUnitName();
StorylineHistory history = rollbackUnitName != null
? storyLineService.replaceUserToBack(message.getPersonId(), rollbackUnitName).orElseThrow(rollBackException("Юнит для возвращения не был найден"))
: storyLineService.replaceUserToBack(message.getPersonId(), countToBack).orElseThrow(rollBackException("Юнит для возвращения не был найден"));
final String unitName = history.getUnitName();
final MainUnit nextUnit = storyLineService.getUnitByName(unitName).orElse(unit);
final T oldMessage = (T) history.getMessage();
return UnitRequest.of(nextUnit, oldMessage);
}
}

View File

@ -6,7 +6,7 @@
<groupId>dev.struchkov.godfather</groupId>
<artifactId>godfather-bot</artifactId>
<version>0.0.9</version>
<version>0.0.10</version>
<packaging>pom</packaging>
<modules>
@ -32,7 +32,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<godfather.ver>0.0.9</godfather.ver>
<godfather.ver>0.0.10</godfather.ver>
<godfather.context.ver>${godfather.ver}</godfather.context.ver>
<godfather.core.ver>${godfather.ver}</godfather.core.ver>