From 7e4264a9e6b63658e66be5687b955f76b848e6ee Mon Sep 17 00:00:00 2001 From: Struchkov Mark Date: Sun, 26 Jun 2022 22:49:15 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=B0=D1=8F=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=BD=D0=BE=D0=B2=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BC=D0=B0=D0=BF=D0=BF=D0=B8=D0=BD=D0=B3=D0=B0=20?= =?UTF-8?q?=D1=8E=D0=BD=D0=B8=D1=82=D0=B0=20=D0=B8=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?StoryLine.=20=D0=A2=D0=B0=D0=BA=D0=B6=D0=B5=20=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BB=20=D0=BA=D0=BE=D0=B4=20=D0=BF=D0=BE=D0=B4=20=D0=BA?= =?UTF-8?q?=D0=BE=D1=80=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5?= =?UTF-8?q?=D0=BA=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot-context/pom.xml | 2 +- .../context/domain/UnitDefinition.java | 77 ++++++++ .../godfather/context/domain/UnitPointer.java | 36 ++++ .../context/domain/annotation/Unit.java | 20 ++ .../domain/keyboard/button/SimpleButton.java | 2 +- .../keyboard/simple/SimpleKeyBoard.java | 2 +- .../exception/UnitConfigException.java | 6 +- .../repository/PersonSettingRepository.java | 16 ++ .../repository/UnitPointerRepository.java | 19 ++ .../local/PersonSettingLocalRepository.java | 37 ++++ .../impl/local/UnitPointLocalRepository.java | 31 +++ .../context/service/EventProvider.java | 9 + .../context/service/PersonSettingService.java | 18 ++ .../context/service/UnitPointerService.java | 21 ++ .../context/service/sender/Sending.java | 2 - .../{KeyBoards.java => SimpleKeyBoards.java} | 12 +- bot-core/pom.xml | 2 +- .../godfather/core/GeneralAutoResponder.java | 122 +++++++----- .../struchkov/godfather/core/StoryLine.java | 55 ++++++ .../godfather/core/StorylineMaker.java | 185 ++++++++++++++++++ .../core/domain/unit/AnswerCheck.java | 26 ++- .../core/domain/unit/AnswerProcessing.java | 26 ++- .../core/domain/unit/AnswerSave.java | 26 ++- .../core/domain/unit/AnswerText.java | 26 ++- .../core/domain/unit/AnswerTimer.java | 25 ++- .../core/domain/unit/AnswerValidity.java | 26 ++- .../godfather/core/domain/unit/LazyUnit.java | 34 ++++ .../godfather/core/domain/unit/MainUnit.java | 41 +++- .../godfather/core/service/Accessibility.java | 9 + .../service/PersonSettingServiceImpl.java | 42 ++++ .../core/service/UnitPointerServiceImpl.java | 33 ++++ .../provider/EventStoryLineProvider.java | 20 ++ pom.xml | 6 +- 33 files changed, 936 insertions(+), 78 deletions(-) create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitDefinition.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitPointer.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/domain/annotation/Unit.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/repository/PersonSettingRepository.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/repository/UnitPointerRepository.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/PersonSettingLocalRepository.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/UnitPointLocalRepository.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/service/EventProvider.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/service/PersonSettingService.java create mode 100644 bot-context/src/main/java/dev/struchkov/godfather/context/service/UnitPointerService.java rename bot-context/src/main/java/dev/struchkov/godfather/context/utils/{KeyBoards.java => SimpleKeyBoards.java} (97%) create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/StoryLine.java create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/StorylineMaker.java create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/LazyUnit.java create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/service/Accessibility.java create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/service/PersonSettingServiceImpl.java create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/service/UnitPointerServiceImpl.java create mode 100644 bot-core/src/main/java/dev/struchkov/godfather/core/service/provider/EventStoryLineProvider.java diff --git a/bot-context/pom.xml b/bot-context/pom.xml index a8eb960..24a18f5 100644 --- a/bot-context/pom.xml +++ b/bot-context/pom.xml @@ -6,7 +6,7 @@ dev.struchkov.godfather godfather-bot - 0.0.6 + 0.0.7 bot-context diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitDefinition.java b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitDefinition.java new file mode 100644 index 0000000..e933d3d --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitDefinition.java @@ -0,0 +1,77 @@ +package dev.struchkov.godfather.context.domain; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +public class UnitDefinition { + + private final Set nextUnitNames = new HashSet<>(); + private final Set dependentUnits = new HashSet<>(); + + private String name; + private Object objectConfig; + private Method method; + private boolean lazy; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Object getObjectConfig() { + return objectConfig; + } + + public void setObjectConfig(Object objectConfig) { + this.objectConfig = objectConfig; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + + public Set getNextUnitNames() { + return new HashSet<>(nextUnitNames); + } + + public void setNextUnitNames(Set nextUnitNames) { + this.nextUnitNames.addAll(nextUnitNames); + } + + public void setNextUnitName(String nextUnitName) { + this.nextUnitNames.add(nextUnitName); + } + + public void removeNextUnit(String nextUnitName) { + this.nextUnitNames.remove(nextUnitName); + } + + public void removeDependentUnit(String dependentUnitName) { + this.dependentUnits.remove(dependentUnitName); + } + + public Set getDependentUnits() { + return new HashSet<>(dependentUnits); + } + + public void setDependentUnits(Set dependentUnitNames) { + this.dependentUnits.addAll(dependentUnitNames); + } + + public boolean isLazy() { + return lazy; + } + + public void setLazy(boolean lazy) { + this.lazy = lazy; + } + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitPointer.java b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitPointer.java new file mode 100644 index 0000000..882adfc --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/UnitPointer.java @@ -0,0 +1,36 @@ +package dev.struchkov.godfather.context.domain; + +import java.util.Objects; + +public class UnitPointer { + + private Long personId; + private String unitName; + + public UnitPointer(Long personId, String unitName) { + this.personId = personId; + this.unitName = unitName; + } + + public Long getPersonId() { + return personId; + } + + public String getUnitName() { + return unitName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UnitPointer that = (UnitPointer) o; + return Objects.equals(personId, that.personId) && Objects.equals(unitName, that.unitName); + } + + @Override + public int hashCode() { + return Objects.hash(personId, unitName); + } + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/annotation/Unit.java b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/annotation/Unit.java new file mode 100644 index 0000000..06dcc80 --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/annotation/Unit.java @@ -0,0 +1,20 @@ +package dev.struchkov.godfather.context.domain.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target({METHOD, PARAMETER}) +public @interface Unit { + + String value() default ""; + + boolean lazy() default false; + + boolean mainUnit() default false; + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/button/SimpleButton.java b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/button/SimpleButton.java index eba5ff8..6cb0d7e 100644 --- a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/button/SimpleButton.java +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/button/SimpleButton.java @@ -33,7 +33,7 @@ public class SimpleButton implements KeyBoardButton { } public static SimpleButton simpleButton(@NotNull String label) { - return new SimpleButton(label, label); + return new SimpleButton(label, null); } public String getLabel() { diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/simple/SimpleKeyBoard.java b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/simple/SimpleKeyBoard.java index 8f737d4..1b32b53 100644 --- a/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/simple/SimpleKeyBoard.java +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/domain/keyboard/simple/SimpleKeyBoard.java @@ -33,7 +33,7 @@ public class SimpleKeyBoard implements KeyBoard { return new SimpleKeyBoard(List.of(line)); } - public static Builder build() { + public static Builder builder() { return new Builder(); } diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/exception/UnitConfigException.java b/bot-context/src/main/java/dev/struchkov/godfather/context/exception/UnitConfigException.java index a88c6a5..6f7c4e3 100644 --- a/bot-context/src/main/java/dev/struchkov/godfather/context/exception/UnitConfigException.java +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/exception/UnitConfigException.java @@ -16,8 +16,12 @@ public class UnitConfigException extends AppBotException{ super(message); } + public UnitConfigException(String message, Object... objects) { + super(MessageFormat.format(message, objects)); + } + public static Supplier unitConfigException(String message, Object... objects) { - return () -> new NotFoundException(MessageFormat.format(message, objects)); + return () -> new NotFoundException(message, objects); } } diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/repository/PersonSettingRepository.java b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/PersonSettingRepository.java new file mode 100644 index 0000000..c6883d0 --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/PersonSettingRepository.java @@ -0,0 +1,16 @@ +package dev.struchkov.godfather.context.repository; + +import java.util.Optional; +import java.util.Set; + +public interface PersonSettingRepository { + + Set findAllByAllowedProcessing(Set personIds); + + void disableMessageProcessing(Long personId); + + void enableMessageProcessing(Long personId); + + Optional findStateByPersonId(Long personId); + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/repository/UnitPointerRepository.java b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/UnitPointerRepository.java new file mode 100644 index 0000000..d261962 --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/UnitPointerRepository.java @@ -0,0 +1,19 @@ +package dev.struchkov.godfather.context.repository; + +import dev.struchkov.godfather.context.domain.UnitPointer; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +/** + * Контракт для сохранения позиции пользователя в сценарии. + */ +public interface UnitPointerRepository { + + UnitPointer save(@NotNull UnitPointer unitPointer); + + Optional findUnitNameByPersonId(@NotNull Long personId); + + void removeByPersonId(@NotNull Long personId); + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/PersonSettingLocalRepository.java b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/PersonSettingLocalRepository.java new file mode 100644 index 0000000..0b301f6 --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/PersonSettingLocalRepository.java @@ -0,0 +1,37 @@ +package dev.struchkov.godfather.context.repository.impl.local; + +import dev.struchkov.godfather.context.repository.PersonSettingRepository; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +public class PersonSettingLocalRepository implements PersonSettingRepository { + + private final Map map = new HashMap<>(); + + @Override + public Set findAllByAllowedProcessing(Set personIds) { + return personIds.stream() + .filter(map::get) + .collect(Collectors.toSet()); + } + + @Override + public void disableMessageProcessing(Long personId) { + map.put(personId, false); + } + + @Override + public void enableMessageProcessing(Long personId) { + map.put(personId, true); + } + + @Override + public Optional findStateByPersonId(Long personId) { + return Optional.ofNullable(map.get(personId)); + } + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/UnitPointLocalRepository.java b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/UnitPointLocalRepository.java new file mode 100644 index 0000000..88e9b0b --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/repository/impl/local/UnitPointLocalRepository.java @@ -0,0 +1,31 @@ +package dev.struchkov.godfather.context.repository.impl.local; + +import dev.struchkov.godfather.context.domain.UnitPointer; +import dev.struchkov.godfather.context.repository.UnitPointerRepository; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class UnitPointLocalRepository implements UnitPointerRepository { + + public static final Map map = new HashMap<>(); + + @Override + public UnitPointer save(@NotNull UnitPointer unitPointer) { + map.put(unitPointer.getPersonId(), unitPointer.getUnitName()); + return unitPointer; + } + + @Override + public Optional findUnitNameByPersonId(@NotNull Long personId) { + return Optional.ofNullable(map.get(personId)); + } + + @Override + public void removeByPersonId(@NotNull Long personId) { + map.remove(personId); + } + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/service/EventProvider.java b/bot-context/src/main/java/dev/struchkov/godfather/context/service/EventProvider.java new file mode 100644 index 0000000..26b8a6d --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/service/EventProvider.java @@ -0,0 +1,9 @@ +package dev.struchkov.godfather.context.service; + +import dev.struchkov.godfather.context.domain.content.Message; + +public interface EventProvider { + + void sendEvent(M message); + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/service/PersonSettingService.java b/bot-context/src/main/java/dev/struchkov/godfather/context/service/PersonSettingService.java new file mode 100644 index 0000000..972d0ae --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/service/PersonSettingService.java @@ -0,0 +1,18 @@ +package dev.struchkov.godfather.context.service; + +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; +import java.util.Set; + +public interface PersonSettingService { + + Set getAllPersonIdDisableMessages(@NotNull Set personIds); + + Optional getStateProcessingByPersonId(@NotNull Long personId); + + void disableMessageProcessing(@NotNull Long personId); + + void enableMessageProcessing(@NotNull Long personId); + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/service/UnitPointerService.java b/bot-context/src/main/java/dev/struchkov/godfather/context/service/UnitPointerService.java new file mode 100644 index 0000000..404429f --- /dev/null +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/service/UnitPointerService.java @@ -0,0 +1,21 @@ +package dev.struchkov.godfather.context.service; + +import dev.struchkov.godfather.context.domain.UnitPointer; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +/** + * Сервис для взаимодействия с сущностью {@link UnitPointer}. + * + * @author upagge [07/07/2019] + */ +public interface UnitPointerService { + + UnitPointer save(@NotNull UnitPointer unitPointer); + + Optional getUnitNameByPersonId(@NotNull Long personId); + + void removeByPersonId(@NotNull Long personId); + +} diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/service/sender/Sending.java b/bot-context/src/main/java/dev/struchkov/godfather/context/service/sender/Sending.java index c9a016a..038c933 100644 --- a/bot-context/src/main/java/dev/struchkov/godfather/context/service/sender/Sending.java +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/service/sender/Sending.java @@ -18,8 +18,6 @@ public interface Sending { */ void send(@NotNull Long personId, @NotNull BoxAnswer boxAnswer); - void send(@NotNull Long contentId, @NotNull Long personId, @NotNull BoxAnswer boxAnswer); - /** * Возвращает тип объекта отправляющего ответ пользователя. В зависимости от типа ответ будет отправлен с помощью * разных методов. diff --git a/bot-context/src/main/java/dev/struchkov/godfather/context/utils/KeyBoards.java b/bot-context/src/main/java/dev/struchkov/godfather/context/utils/SimpleKeyBoards.java similarity index 97% rename from bot-context/src/main/java/dev/struchkov/godfather/context/utils/KeyBoards.java rename to bot-context/src/main/java/dev/struchkov/godfather/context/utils/SimpleKeyBoards.java index 178c0f8..3aee316 100644 --- a/bot-context/src/main/java/dev/struchkov/godfather/context/utils/KeyBoards.java +++ b/bot-context/src/main/java/dev/struchkov/godfather/context/utils/SimpleKeyBoards.java @@ -12,12 +12,12 @@ import java.util.List; * * @author upagge [08/07/2019] */ -public class KeyBoards { +public class SimpleKeyBoards { public static final SimpleButton YES_BUTTON = SimpleButton.simpleButton("Да", "{\"button\": \"yes\"}"); public static final SimpleButton NO_BUTTON = SimpleButton.simpleButton("Нет", "{\"button\": \"no\"}"); - private KeyBoards() { + private SimpleKeyBoards() { throw new IllegalStateException(); } @@ -27,7 +27,7 @@ public class KeyBoards { * @return {@link SimpleKeyBoard} */ public static SimpleKeyBoard keyBoardYesNo() { - return SimpleKeyBoard.build().line( + return SimpleKeyBoard.builder().line( SimpleKeyBoardLine.builder().button(YES_BUTTON).button(NO_BUTTON).build() ).build(); } @@ -39,7 +39,7 @@ public class KeyBoards { * @return {@link SimpleKeyBoard} */ public static SimpleKeyBoard verticalMenuString(List labelButtons) { - final SimpleKeyBoard.Builder keyBoard = SimpleKeyBoard.build(); + final SimpleKeyBoard.Builder keyBoard = SimpleKeyBoard.builder(); for (String labelButton : labelButtons) { final SimpleButton simpleButton = SimpleButton.simpleButton(labelButton, "{\"button\": \"" + labelButton + "\"}"); keyBoard.line(SimpleKeyBoardLine.builder().button(simpleButton).build()); @@ -74,7 +74,7 @@ public class KeyBoards { * @return {@link SimpleKeyBoard} */ public static SimpleKeyBoard verticalDuoMenuString(List labelButton) { - final SimpleKeyBoard.Builder keyBoard = SimpleKeyBoard.build(); + final SimpleKeyBoard.Builder keyBoard = SimpleKeyBoard.builder(); boolean flag = true; SimpleKeyBoardLine.Builder keyBoardLine = SimpleKeyBoardLine.builder(); for (int i = 0; i <= labelButton.size() - 1; i++) { @@ -102,7 +102,7 @@ public class KeyBoards { * @return {@link SimpleKeyBoard} */ public static SimpleKeyBoard verticalMenuButton(List simpleButtons) { - final SimpleKeyBoard.Builder keyBoard = SimpleKeyBoard.build(); + final SimpleKeyBoard.Builder keyBoard = SimpleKeyBoard.builder(); for (SimpleButton simpleButton : simpleButtons) { keyBoard.line(SimpleKeyBoardLine.builder().button(simpleButton).build()); } diff --git a/bot-core/pom.xml b/bot-core/pom.xml index 2e67d3f..5e4db41 100644 --- a/bot-core/pom.xml +++ b/bot-core/pom.xml @@ -6,7 +6,7 @@ dev.struchkov.godfather godfather-bot - 0.0.6 + 0.0.7 bot-core diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/GeneralAutoResponder.java b/bot-core/src/main/java/dev/struchkov/godfather/core/GeneralAutoResponder.java index c307260..508f40a 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/GeneralAutoResponder.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/GeneralAutoResponder.java @@ -1,16 +1,17 @@ package dev.struchkov.godfather.core; -import dev.struchkov.autoresponder.AutoResponder; -import dev.struchkov.autoresponder.entity.UnitPointer; -import dev.struchkov.autoresponder.repository.UnitPointerRepository; -import dev.struchkov.autoresponder.service.UnitPointerServiceImpl; +import dev.struchkov.autoresponder.Responder; +import dev.struchkov.autoresponder.entity.Unit; +import dev.struchkov.godfather.context.domain.UnitPointer; import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.exception.ConfigAppException; -import dev.struchkov.godfather.context.service.MessageService; import dev.struchkov.godfather.context.service.Modifiable; +import dev.struchkov.godfather.context.service.PersonSettingService; +import dev.struchkov.godfather.context.service.UnitPointerService; import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.core.domain.unit.UnitActiveType; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.service.action.ActionUnit; import dev.struchkov.godfather.core.service.action.AnswerCheckAction; import dev.struchkov.godfather.core.service.action.AnswerProcessingAction; @@ -27,26 +28,26 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.TimerTask; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; +import java.util.stream.Collectors; -public class GeneralAutoResponder extends TimerTask { +public class GeneralAutoResponder { + + private final PersonSettingService personSettingService; + private final UnitPointerService unitPointerService; + private final StoryLine storyLine; - protected final AutoResponder autoResponder; - private final MessageService messageService; protected Map> actionUnitMap = new HashMap<>(); - protected List> modifiables; - private ExecutorService executorService = Executors.newFixedThreadPool(10); + protected List> modifiable; - protected GeneralAutoResponder(Set menuUnit, - Sending sending, - MessageService messageService, - UnitPointerRepository unitPointerRepository + protected GeneralAutoResponder( + Sending sending, + PersonSettingService personSettingService, + UnitPointerService unitPointerService, + List unitConfigurations ) { - this.messageService = messageService; - autoResponder = new AutoResponder<>(new UnitPointerServiceImpl<>(unitPointerRepository), menuUnit); + this.personSettingService = personSettingService; + this.unitPointerService = unitPointerService; + this.storyLine = new StorylineMaker(unitConfigurations).createStoryLine(); init(sending); } @@ -57,8 +58,8 @@ public class GeneralAutoResponder extends TimerTask { actionUnitMap.put(TypeUnit.VALIDITY, new AnswerValidityAction()); } - public void initModifiables(List> modifiables) { - this.modifiables = modifiables; + public void initModifiable(List> modifiable) { + this.modifiable = modifiable; } public void initActionUnit(String typeUnit, ActionUnit actionUnit) { @@ -69,10 +70,6 @@ public class GeneralAutoResponder extends TimerTask { } } - public void initDefaultUnit(U defaultUnit) { - autoResponder.setDefaultUnit(defaultUnit); - } - public void initSaveAction(AnswerSaveAction answerSaveAction) { actionUnitMap.put(TypeUnit.SAVE, answerSaveAction); } @@ -81,33 +78,56 @@ public class GeneralAutoResponder extends TimerTask { actionUnitMap.put(TypeUnit.TIMER, new AnswerTimerAction(timerService, this)); } - public void setDefaultUnit(MainUnit mainUnit) { - autoResponder.setDefaultUnit(mainUnit); - } - - public void checkNewMessage() { - List eventByTime = messageService.getNewMessage(); - if (eventByTime != null && !eventByTime.isEmpty()) { - executorService.execute( - () -> eventByTime.parallelStream().forEach(processing()) - ); + public void processingNewMessage(T newMessage) { + if (newMessage != null) { + final boolean state = personSettingService.getStateProcessingByPersonId(newMessage.getPersonId()).orElse(true); + if (state) { + processing(newMessage); + } } } - private Consumer processing() { - return event -> { - if (modifiables != null) { - modifiables.forEach(modifiable -> modifiable.change(event)); - } - autoResponder.answer(event.getPersonId(), event.getText()).ifPresent(unitAnswer -> answer(event, unitAnswer)); - }; + public void processingNewMessages(List newMessages) { + if (newMessages != null && !newMessages.isEmpty()) { + final Set personIds = newMessages.stream() + .map(Message::getPersonId) + .collect(Collectors.toSet()); + final Set disableIds = personSettingService.getAllPersonIdDisableMessages(personIds); + final List allowedMessages = newMessages.stream() + .filter(message -> !disableIds.contains(message.getPersonId())) + .toList(); + allowedMessages.parallelStream().forEach(this::processing); + } } - public void answer(T event, MainUnit unitAnswer) { - unitAnswer = getAction(event, unitAnswer); - unitAnswer = activeUnitAfter(unitAnswer, event); - if (!(autoResponder.getDefaultUnit() != null && autoResponder.getDefaultUnit().equals(unitAnswer))) { - autoResponder.getUnitPointerService().save(new UnitPointer<>(event.getPersonId(), unitAnswer)); + private void processing(T message) { + if (modifiable != null) { + modifiable.forEach(m -> m.change(message)); + } + final Set units = unitPointerService.getUnitNameByPersonId(message.getPersonId()) + .flatMap(storyLine::getUnit) + .map(Unit::getNextUnits) + .filter(mainUnits -> !mainUnits.isEmpty()) + .orElse(storyLine.getStartingUnits()); + final Optional optAnswer = Responder.nextUnit(message.getText(), units); + if (optAnswer.isPresent()) { + final MainUnit answer = optAnswer.get(); + if (checkPermission(answer.getAccessibility(), message)) { + answer(message, answer); + } + } + } + + private boolean checkPermission(Optional accessibility, T message) { + return accessibility.isEmpty() || accessibility.get().check(message); + } + + public void answer(T message, MainUnit unitAnswer) { + unitAnswer = getAction(message, unitAnswer); + unitAnswer = activeUnitAfter(unitAnswer, message); + final Optional optDefaultUnit = storyLine.getDefaultUnit(); + if (optDefaultUnit.isEmpty() || !optDefaultUnit.get().equals(unitAnswer)) { + unitPointerService.save(new UnitPointer(message.getPersonId(), unitAnswer.getName())); } } @@ -134,9 +154,9 @@ public class GeneralAutoResponder extends TimerTask { } } - @Override - public void run() { - checkNewMessage(); + //TODO [22.06.2022]: Временное решение для ленивой инициализации + public void link(String firstName, String secondName) { + storyLine.link(firstName, secondName); } } diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/StoryLine.java b/bot-core/src/main/java/dev/struchkov/godfather/core/StoryLine.java new file mode 100644 index 0000000..39cc4ec --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/StoryLine.java @@ -0,0 +1,55 @@ +package dev.struchkov.godfather.core; + +import dev.struchkov.godfather.core.domain.unit.MainUnit; +import dev.struchkov.haiti.utils.Inspector; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public class StoryLine { + + private MainUnit defaultUnit; + private final Set startingUnits = new HashSet<>(); + private final Map units = new HashMap<>(); + + public StoryLine(Set startingUnits, Map units) { + this.startingUnits.addAll(startingUnits); + this.units.putAll(units); + } + + public void setDefaultUnit(MainUnit defaultUnit) { + this.defaultUnit = defaultUnit; + } + + public Optional getDefaultUnit() { + return Optional.ofNullable(defaultUnit); + } + + /** + * Получить юнит по названию. + * + * @param unitName Название юнита. + */ + public Optional getUnit(String unitName) { + Inspector.isNotNull(unitName); + return Optional.ofNullable(units.get(unitName)); + } + + public Set getStartingUnits() { + return startingUnits; + } + + //TODO [22.06.2022]: Временное решение ленивой связки юнитов, пока не будет реализован нормальный механизм. + public void link(@NotNull String firstName, @NotNull String secondName) { + Inspector.isNotNull(firstName, secondName); + final MainUnit firstUnit = units.get(firstName); + final MainUnit secondUnit = units.get(secondName); + Inspector.isNotNull(firstUnit, secondUnit); + firstUnit.getNextUnits().add(secondUnit); + } + +} diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/StorylineMaker.java b/bot-core/src/main/java/dev/struchkov/godfather/core/StorylineMaker.java new file mode 100644 index 0000000..efb8827 --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/StorylineMaker.java @@ -0,0 +1,185 @@ +package dev.struchkov.godfather.core; + +import dev.struchkov.godfather.context.domain.UnitDefinition; +import dev.struchkov.godfather.context.domain.annotation.Unit; +import dev.struchkov.godfather.context.exception.UnitConfigException; +import dev.struchkov.godfather.core.domain.unit.LazyUnit; +import dev.struchkov.godfather.core.domain.unit.MainUnit; +import dev.struchkov.haiti.utils.Inspector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static dev.struchkov.godfather.context.exception.UnitConfigException.unitConfigException; + +public class StorylineMaker { + + private static final Logger log = LoggerFactory.getLogger(StorylineMaker.class); + + private final List configurations = new ArrayList<>(); + + private final Map unitDefinitions = new HashMap<>(); + private final Map unitMap = new HashMap<>(); + private final Set lazyUnits = new HashSet<>(); + private final Set mainUnits = new HashSet<>(); + + public StorylineMaker(List unitConfigurations) { + this.configurations.addAll(unitConfigurations); + } + + public Map getUnitDefinitions() { + return unitDefinitions; + } + + public Map getUnitMap() { + return unitMap; + } + + public StoryLine createStoryLine() { + generateUnitDefinitions(); + try { + createUnitMap(); + createLazy(); + final Set mainUnit = getMainUnit(); + return new StoryLine(mainUnit, unitMap); + } catch (IllegalAccessException | InvocationTargetException e) { + log.error(e.getMessage(), e); + } + throw new UnitConfigException("Ошибка построения StoryLine"); + } + + private Set getMainUnit() { + Inspector.isNotEmpty(mainUnits, unitConfigException("Не задан ни один mainUnit. Установите хотя бы для одного Unit флаг mainUnit")); + return mainUnits.stream() + .map(unitMap::get) + .collect(Collectors.toSet()); + } + + private void createLazy() throws IllegalAccessException, InvocationTargetException { + final List lazyDefinitions = unitDefinitions.values().stream() + .filter(UnitDefinition::isLazy) + .toList(); + for (UnitDefinition lazyDefinition : lazyDefinitions) { + final MainUnit lazyUnit = createUnit(lazyDefinition); + unitMap.put(lazyDefinition.getName(), lazyUnit); + for (String dependentUnit : lazyDefinition.getDependentUnits()) { + final MainUnit mainUnit = unitMap.get(dependentUnit); + final Set nextUnits = mainUnit.getNextUnits(); + if (nextUnits != null) { + nextUnits.add(lazyUnit); + } + } + } + } + + private void createUnitMap() throws IllegalAccessException, InvocationTargetException { + for (UnitDefinition unitDefinition : unitDefinitions.values()) { + if (!unitMap.containsKey(unitDefinition.getName())) { + final Set nextUnitNames = unitDefinition.getNextUnitNames(); + if (nextUnitNames.isEmpty() || unitMap.keySet().containsAll(nextUnitNames)) { + createUnit(unitDefinition); + } else if (unitDefinition.isLazy()) { + createLazyUnit(unitDefinition); + } + } + } + } + + private void createLazyUnit(UnitDefinition unitDefinition) { + final String unitName = unitDefinition.getName(); + unitMap.put(unitName, LazyUnit.create(unitName, unitDefinition)); + } + + private MainUnit createUnit(UnitDefinition unitDefinition) throws IllegalAccessException, InvocationTargetException { + + final Object objectConfig = unitDefinition.getObjectConfig(); + final String currentUnitName = unitDefinition.getName(); + final Method method = unitDefinition.getMethod(); + final Object[] nextUnits = Arrays.stream(method.getParameters()) + .filter(parameter -> parameter.isAnnotationPresent(Unit.class)) + .map(parameter -> parameter.getAnnotation(Unit.class)) + .map(Unit::value) + .map(unitMap::get) + .toArray(); + MainUnit newUnit = (MainUnit) method.invoke(objectConfig, nextUnits); + newUnit.setName(currentUnitName); + + unitMap.put(currentUnitName, newUnit); + + final Set dependentUnitsName = unitDefinition.getDependentUnits(); + dependentUnitsName.removeAll(lazyUnits); + for (String dependentUnitName : dependentUnitsName) { + final Set dependentNextUnitNames = unitDefinitions.get(dependentUnitName).getNextUnitNames(); + if (unitMap.keySet().containsAll(dependentNextUnitNames)) { + createUnit(unitDefinitions.get(dependentUnitName)); + } + } + + return newUnit; + } + + private void generateUnitDefinitions() { + final Map> dependentUnits = new HashMap<>(); + + for (Object config : configurations) { + final Class classUnitConfig = config.getClass(); + + for (Method method : classUnitConfig.getDeclaredMethods()) { + if (method.isAnnotationPresent(Unit.class)) { + final Unit unitConfig = method.getAnnotation(Unit.class); + + final String unitName = unitConfig.value(); + + final UnitDefinition unitDefinition = new UnitDefinition(); + unitDefinition.setName(unitName); + unitDefinition.setMethod(method); + unitDefinition.setObjectConfig(config); + unitDefinition.setLazy(unitConfig.lazy()); + + if (unitConfig.lazy()) { + lazyUnits.add(unitName); + } + if (unitConfig.mainUnit()) { + mainUnits.add(unitName); + } + + final Parameter[] nextUnits = method.getParameters(); + if (nextUnits.length > 0) { + for (Parameter nextUnit : nextUnits) { + if (nextUnit.isAnnotationPresent(Unit.class)) { + final Unit nextUnitConfig = nextUnit.getAnnotation(Unit.class); + final String nextUnitName = nextUnitConfig.value(); + unitDefinition.setNextUnitName(nextUnitName); + dependentUnits.computeIfAbsent(nextUnitName, k -> new HashSet<>()); + dependentUnits.get(nextUnitName).add(unitName); + } + } + } + + unitDefinitions.put(unitDefinition.getName(), unitDefinition); + } + } + } + + for (Map.Entry> entry : dependentUnits.entrySet()) { + final UnitDefinition unitDefinition = unitDefinitions.get(entry.getKey()); + if (unitDefinition != null) { + unitDefinition.setDependentUnits(entry.getValue()); + } else { + throw new UnitConfigException("Ошибка связи юнитов. Проблема с описанием {0} юнита. Возможно вы не указали класс конфигурации для этого юнита.", entry.getKey()); + } + } + } + +} diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerCheck.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerCheck.java index 19a8359..2ad53b4 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerCheck.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerCheck.java @@ -2,6 +2,7 @@ package dev.struchkov.godfather.core.domain.unit; import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.service.usercode.CheckData; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.utils.TypeUnit; import java.util.HashSet; @@ -35,7 +36,18 @@ public class AnswerCheck extends MainUnit { private final CheckData check; private AnswerCheck(Builder builder) { - super(builder.keyWords, builder.phrase, builder.pattern, builder.matchThreshold, builder.priority, null, builder.activeType, TypeUnit.CHECK); + super( + builder.name, + builder.keyWords, + builder.phrase, + builder.pattern, + builder.matchThreshold, + builder.priority, + new HashSet<>(), + builder.activeType, + builder.accessibility, + TypeUnit.CHECK + ); unitTrue = builder.unitTrue; unitFalse = builder.unitFalse; check = builder.check; @@ -58,6 +70,7 @@ public class AnswerCheck extends MainUnit { } public static final class Builder { + private String name; private Set keyWords = new HashSet<>(); private String phrase; private Pattern pattern; @@ -67,10 +80,16 @@ public class AnswerCheck extends MainUnit { private MainUnit unitFalse; private CheckData check; private UnitActiveType activeType; + private Accessibility accessibility; private Builder() { } + public Builder name(String name) { + this.name = name; + return this; + } + public Builder keyWords(Set val) { keyWords = val; return this; @@ -116,6 +135,11 @@ public class AnswerCheck extends MainUnit { return this; } + public Builder accessibility(Accessibility val) { + accessibility = val; + return this; + } + public Builder activeType(UnitActiveType val) { activeType = val; return this; diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerProcessing.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerProcessing.java index 62f600f..4febdd2 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerProcessing.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerProcessing.java @@ -3,6 +3,7 @@ package dev.struchkov.godfather.core.domain.unit; import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.context.service.usercode.ProcessingData; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.utils.TypeUnit; import java.util.HashSet; @@ -27,7 +28,18 @@ public class AnswerProcessing extends MainUnit { private final Sending sending; private AnswerProcessing(Builder builder) { - super(builder.keyWords, builder.phrase, builder.pattern, builder.matchThreshold, builder.priority, builder.nextUnits, builder.activeType, TypeUnit.PROCESSING); + super( + builder.name, + builder.keyWords, + builder.phrase, + builder.pattern, + builder.matchThreshold, + builder.priority, + builder.nextUnits, + builder.activeType, + builder.accessibility, + TypeUnit.PROCESSING + ); processingData = builder.processingData; sending = builder.sending; } @@ -45,6 +57,7 @@ public class AnswerProcessing extends MainUnit { } public static final class Builder { + private String name; private Set keyWords = new HashSet<>(); private String phrase; private Pattern pattern; @@ -54,10 +67,16 @@ public class AnswerProcessing extends MainUnit { private ProcessingData processingData; private Sending sending; private UnitActiveType activeType; + private Accessibility accessibility; private Builder() { } + public Builder name(String name) { + this.name = name; + return this; + } + public Builder processingData(ProcessingData val) { processingData = val; return this; @@ -108,6 +127,11 @@ public class AnswerProcessing extends MainUnit { return this; } + public Builder accessibility(Accessibility val) { + accessibility = val; + return this; + } + public Builder activeType(UnitActiveType val) { activeType = val; return this; diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerSave.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerSave.java index 0fb1e86..fac35c3 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerSave.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerSave.java @@ -1,6 +1,7 @@ package dev.struchkov.godfather.core.domain.unit; import dev.struchkov.godfather.context.domain.content.Message; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.service.save.CheckSave; import dev.struchkov.godfather.core.service.save.Preservable; import dev.struchkov.godfather.core.service.save.data.PreservableData; @@ -49,7 +50,18 @@ public class AnswerSave extends MainUnit { private final CheckSave checkSave; private AnswerSave(Builder builder) { - super(builder.keyWords, builder.phrase, builder.pattern, builder.matchThreshold, builder.priority, builder.nextUnits, (builder.hidden) ? UnitActiveType.AFTER : UnitActiveType.DEFAULT, TypeUnit.SAVE); + super( + builder.name, + builder.keyWords, + builder.phrase, + builder.pattern, + builder.matchThreshold, + builder.priority, + builder.nextUnits, + (builder.hidden) ? UnitActiveType.AFTER : UnitActiveType.DEFAULT, + builder.accessibility, + TypeUnit.SAVE + ); maintenanceNextUnit(nextUnits); preservable = builder.preservable; key = builder.key; @@ -94,6 +106,7 @@ public class AnswerSave extends MainUnit { } public static final class Builder { + private String name; private Set keyWords = new HashSet<>(); private String phrase; private Pattern pattern; @@ -106,10 +119,16 @@ public class AnswerSave extends MainUnit { private PreservableData preservableData; private boolean hidden; private CheckSave checkSave; + private Accessibility accessibility; private Builder() { } + public Builder name(String name) { + this.name = name; + return this; + } + public Builder keyWords(Set val) { keyWords = val; return this; @@ -180,6 +199,11 @@ public class AnswerSave extends MainUnit { return this; } + public Builder accessibility(Accessibility val) { + accessibility = val; + return this; + } + public AnswerSave build() { isNotNull(preservable, "Не указан репозиторий для сохранения формы пользователя"); isNotNull(preservableData, "Не указаны данные для сохранения"); diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerText.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerText.java index 4d8340b..beb7dca 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerText.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerText.java @@ -7,6 +7,7 @@ import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.context.service.usercode.Insert; import dev.struchkov.godfather.context.service.usercode.MessageFunction; import dev.struchkov.godfather.context.service.usercode.ProcessingData; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.utils.TypeUnit; import java.util.HashSet; @@ -39,7 +40,18 @@ public class AnswerText extends MainUnit { private final Sending sending; private AnswerText(Builder builder) { - super(builder.keyWords, builder.phrase, builder.pattern, builder.matchThreshold, builder.priority, builder.nextUnits, builder.activeType, TypeUnit.TEXT); + super( + builder.name, + builder.keyWords, + builder.phrase, + builder.pattern, + builder.matchThreshold, + builder.priority, + builder.nextUnits, + builder.activeType, + builder.accessibility, + TypeUnit.TEXT + ); boxAnswer = builder.boxAnswer; insert = builder.insert; sending = builder.sending; @@ -66,6 +78,7 @@ public class AnswerText extends MainUnit { } public static final class Builder { + private String name; private ProcessingData boxAnswer; private Insert insert; private Sending sending; @@ -76,10 +89,16 @@ public class AnswerText extends MainUnit { private Integer priority; private Set nextUnits = new HashSet<>(); private UnitActiveType activeType; + private Accessibility accessibility; private Builder() { } + public Builder name(String name) { + this.name = name; + return this; + } + public Builder message(ProcessingData message) { this.boxAnswer = message; return this; @@ -151,6 +170,11 @@ public class AnswerText extends MainUnit { return this; } + public Builder accessibility(Accessibility val) { + accessibility = val; + return this; + } + public Builder activeType(UnitActiveType val) { activeType = val; return this; diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerTimer.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerTimer.java index ff4638a..2742e52 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerTimer.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerTimer.java @@ -2,6 +2,7 @@ package dev.struchkov.godfather.core.domain.unit; import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.service.usercode.CheckData; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.utils.TypeUnit; import java.util.Set; @@ -38,7 +39,18 @@ public class AnswerTimer extends MainUnit { private final CheckData checkLoop; private AnswerTimer(Builder builder) { - super(builder.keyWords, builder.phrase, builder.pattern, builder.matchThreshold, builder.priority, null, builder.activeType, TypeUnit.TIMER); + super( + builder.name, + builder.keyWords, + builder.phrase, + builder.pattern, + builder.matchThreshold, + builder.priority, + null, + builder.activeType, + builder.accessibility, + TypeUnit.TIMER + ); unitAnswer = builder.unitAnswer; timeDelaySec = builder.timeDelaySec; timeDeathSec = builder.timeDeathSec; @@ -66,6 +78,7 @@ public class AnswerTimer extends MainUnit { } public static final class Builder { + private String name; private MainUnit unitAnswer; private Integer timeDelaySec; private Integer timeDeathSec; @@ -76,9 +89,14 @@ public class AnswerTimer extends MainUnit { private Integer matchThreshold; private Integer priority; private UnitActiveType activeType = UnitActiveType.AFTER; + private Accessibility accessibility; private Builder() { + } + public Builder name(String name) { + this.name = name; + return this; } public Builder unitAnswer(MainUnit val) { @@ -126,6 +144,11 @@ public class AnswerTimer extends MainUnit { return this; } + public Builder accessibility(Accessibility val) { + accessibility = val; + return this; + } + public Builder activeType(UnitActiveType val) { activeType = val; return this; diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerValidity.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerValidity.java index a828a65..0b78c8a 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerValidity.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/AnswerValidity.java @@ -1,5 +1,6 @@ package dev.struchkov.godfather.core.domain.unit; +import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.core.service.ClarificationQuestion; import dev.struchkov.godfather.core.service.save.LocalPreservable; import dev.struchkov.godfather.core.service.save.Preservable; @@ -36,7 +37,18 @@ public class AnswerValidity extends MainUnit { private final ClarificationQuestion clarificationQuestion; private AnswerValidity(Builder builder) { - super(builder.keyWords, builder.phrase, builder.pattern, builder.matchThreshold, builder.priority, builder.nextUnits, UnitActiveType.DEFAULT, TypeUnit.VALIDITY); + super( + builder.name, + builder.keyWords, + builder.phrase, + builder.pattern, + builder.matchThreshold, + builder.priority, + builder.nextUnits, + UnitActiveType.DEFAULT, + builder.accessibility, + TypeUnit.VALIDITY + ); unitYes = builder.unitYes; unitNo = builder.unitNo; unitNull = builder.unitNull; @@ -68,6 +80,7 @@ public class AnswerValidity extends MainUnit { } public static final class Builder { + private String name; private MainUnit unitYes; private MainUnit unitNo; private MainUnit unitNull; @@ -78,10 +91,16 @@ public class AnswerValidity extends MainUnit { private Integer matchThreshold; private Integer priority; private Set nextUnits = new HashSet<>(); + private Accessibility accessibility; private Builder() { } + public Builder name(String name) { + this.name = name; + return this; + } + public Builder unitYes(MainUnit val) { unitYes = val; return this; @@ -147,6 +166,11 @@ public class AnswerValidity extends MainUnit { return this; } + public Builder accessibility(Accessibility val) { + accessibility = val; + return this; + } + public AnswerValidity build() { return new AnswerValidity(this); } diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/LazyUnit.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/LazyUnit.java new file mode 100644 index 0000000..33d46e1 --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/LazyUnit.java @@ -0,0 +1,34 @@ +package dev.struchkov.godfather.core.domain.unit; + +import dev.struchkov.godfather.context.domain.UnitDefinition; +import dev.struchkov.godfather.core.service.Accessibility; + +import java.util.Set; +import java.util.regex.Pattern; + +public class LazyUnit extends MainUnit { + + private final UnitDefinition unitDefinition; + + private LazyUnit( + String name, + Set keyWords, + String phrase, + Pattern pattern, + Integer matchThreshold, + Integer priority, + Set nextUnits, + UnitActiveType activeType, + String type, + UnitDefinition unitDefinition, + Accessibility accessibility + ) { + super(name, keyWords, phrase, pattern, matchThreshold, priority, nextUnits, activeType, accessibility, type); + this.unitDefinition = unitDefinition; + } + + public static LazyUnit create(String name, UnitDefinition unitDefinition) { + return new LazyUnit(name, null, null, null, null, null, null, null, null, unitDefinition, null); + } + +} diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/MainUnit.java b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/MainUnit.java index 44249ac..248212a 100644 --- a/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/MainUnit.java +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/domain/unit/MainUnit.java @@ -1,6 +1,7 @@ package dev.struchkov.godfather.core.domain.unit; import dev.struchkov.autoresponder.entity.Unit; +import dev.struchkov.godfather.core.service.Accessibility; import java.util.Objects; import java.util.Optional; @@ -20,14 +21,28 @@ public abstract class MainUnit extends Unit { */ protected final String type; + /** + * Уникальный идентификатор юнита + */ + private final String uuid = UUID.randomUUID().toString(); + /** * Режим срабатывания Unit-а. */ protected UnitActiveType activeType; - private final String uuid = UUID.randomUUID().toString(); + /** + * Уникальное имя юнита + */ + private String name; + + /** + * Проверка доступа пользователя к юниту. + */ + private Accessibility accessibility; protected MainUnit( + String name, Set keyWords, String phrase, Pattern pattern, @@ -35,10 +50,13 @@ public abstract class MainUnit extends Unit { Integer priority, Set nextUnits, UnitActiveType activeType, + Accessibility accessibility, String type ) { super(keyWords, phrase, pattern, matchThreshold, priority, nextUnits); + this.name = name; this.activeType = Optional.ofNullable(activeType).orElse(UnitActiveType.DEFAULT); + this.accessibility = accessibility; this.type = type; } @@ -46,18 +64,31 @@ public abstract class MainUnit extends Unit { return type; } - public void setActiveType(UnitActiveType activeType) { - this.activeType = activeType; - } - public UnitActiveType getActiveType() { return activeType; } + public void setActiveType(UnitActiveType activeType) { + this.activeType = activeType; + } + public String getUuid() { return uuid; } + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public Optional getAccessibility() { + return Optional.ofNullable(accessibility); + } + + //TODO [27.05.2022]: Возможно стоит добавить имя юнита и убрать остальное @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/service/Accessibility.java b/bot-core/src/main/java/dev/struchkov/godfather/core/service/Accessibility.java new file mode 100644 index 0000000..d801e6f --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/service/Accessibility.java @@ -0,0 +1,9 @@ +package dev.struchkov.godfather.core.service; + +import dev.struchkov.godfather.context.domain.content.Message; + +public interface Accessibility { + + boolean check(Message message); + +} diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/service/PersonSettingServiceImpl.java b/bot-core/src/main/java/dev/struchkov/godfather/core/service/PersonSettingServiceImpl.java new file mode 100644 index 0000000..1a1a0cf --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/service/PersonSettingServiceImpl.java @@ -0,0 +1,42 @@ +package dev.struchkov.godfather.core.service; + +import dev.struchkov.godfather.context.repository.PersonSettingRepository; +import dev.struchkov.godfather.context.service.PersonSettingService; +import dev.struchkov.haiti.utils.Inspector; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; +import java.util.Set; + +public class PersonSettingServiceImpl implements PersonSettingService { + + private final PersonSettingRepository personSettingRepository; + + public PersonSettingServiceImpl(PersonSettingRepository personSettingRepository) { + this.personSettingRepository = personSettingRepository; + } + + @Override + public Set getAllPersonIdDisableMessages(@NotNull Set personIds) { + Inspector.isNotNull(personIds); + return personSettingRepository.findAllByAllowedProcessing(personIds); + } + + @Override + public Optional getStateProcessingByPersonId(@NotNull Long personId) { + return personSettingRepository.findStateByPersonId(personId); + } + + @Override + public void disableMessageProcessing(@NotNull Long personId) { + Inspector.isNotNull(personId); + personSettingRepository.disableMessageProcessing(personId); + } + + @Override + public void enableMessageProcessing(@NotNull Long personId) { + Inspector.isNotNull(personId); + personSettingRepository.enableMessageProcessing(personId); + } + +} diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/service/UnitPointerServiceImpl.java b/bot-core/src/main/java/dev/struchkov/godfather/core/service/UnitPointerServiceImpl.java new file mode 100644 index 0000000..c43bc36 --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/service/UnitPointerServiceImpl.java @@ -0,0 +1,33 @@ +package dev.struchkov.godfather.core.service; + +import dev.struchkov.godfather.context.domain.UnitPointer; +import dev.struchkov.godfather.context.repository.UnitPointerRepository; +import dev.struchkov.godfather.context.service.UnitPointerService; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class UnitPointerServiceImpl implements UnitPointerService { + + private final UnitPointerRepository unitPointerRepository; + + public UnitPointerServiceImpl(UnitPointerRepository unitPointerRepository) { + this.unitPointerRepository = unitPointerRepository; + } + + @Override + public UnitPointer save(@NotNull UnitPointer unitPointer) { + return unitPointerRepository.save(unitPointer); + } + + @Override + public Optional getUnitNameByPersonId(@NotNull Long personId) { + return unitPointerRepository.findUnitNameByPersonId(personId); + } + + @Override + public void removeByPersonId(@NotNull Long personId) { + unitPointerRepository.removeByPersonId(personId); + } + +} diff --git a/bot-core/src/main/java/dev/struchkov/godfather/core/service/provider/EventStoryLineProvider.java b/bot-core/src/main/java/dev/struchkov/godfather/core/service/provider/EventStoryLineProvider.java new file mode 100644 index 0000000..f2a48ac --- /dev/null +++ b/bot-core/src/main/java/dev/struchkov/godfather/core/service/provider/EventStoryLineProvider.java @@ -0,0 +1,20 @@ +package dev.struchkov.godfather.core.service.provider; + +import dev.struchkov.godfather.context.domain.content.Mail; +import dev.struchkov.godfather.context.service.EventProvider; +import dev.struchkov.godfather.core.GeneralAutoResponder; + +public class EventStoryLineProvider implements EventProvider { + + private final GeneralAutoResponder generalAutoResponder; + + public EventStoryLineProvider(GeneralAutoResponder generalAutoResponder) { + this.generalAutoResponder = generalAutoResponder; + } + + @Override + public void sendEvent(Mail message) { + generalAutoResponder.processingNewMessage(message); + } + +} diff --git a/pom.xml b/pom.xml index a96df17..206db28 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.struchkov.godfather godfather-bot - 0.0.6 + 0.0.7 pom @@ -32,12 +32,12 @@ UTF-8 UTF-8 - 0.0.6 + 0.0.7 ${godfather.ver} ${godfather.ver} - 2.0.1 + 3.0.0 1.0.2 2.2