This commit is contained in:
Mark Struchkov 2019-08-21 20:55:54 +03:00
parent 32ec215d81
commit c605a711a6
10 changed files with 101 additions and 103 deletions

View File

@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j;
import org.sadtech.autoresponder.compare.UnitPriorityComparator; import org.sadtech.autoresponder.compare.UnitPriorityComparator;
import org.sadtech.autoresponder.entity.Unit; import org.sadtech.autoresponder.entity.Unit;
import org.sadtech.autoresponder.entity.UnitPointer; import org.sadtech.autoresponder.entity.UnitPointer;
import org.sadtech.autoresponder.exception.NotFoundUnitException;
import org.sadtech.autoresponder.service.UnitPointerService; import org.sadtech.autoresponder.service.UnitPointerService;
import org.sadtech.autoresponder.util.Description; import org.sadtech.autoresponder.util.Description;
import org.sadtech.autoresponder.util.Parser; import org.sadtech.autoresponder.util.Parser;
@ -25,7 +24,7 @@ import java.util.Set;
public class AutoResponder<U extends Unit> { public class AutoResponder<U extends Unit> {
@Description("Компоратор для сортировки Unit-ов") @Description("Компоратор для сортировки Unit-ов")
private final UnitPriorityComparator<U> unitPriorityComparator = new UnitPriorityComparator<>(); private static final UnitPriorityComparator UNIT_PRIORITY_COMPARATOR = new UnitPriorityComparator();
@Description("Начальные юниты, первый запрос приходит на них") @Description("Начальные юниты, первый запрос приходит на них")
private final Set<U> startUnits; private final Set<U> startUnits;
@ -36,9 +35,9 @@ public class AutoResponder<U extends Unit> {
private U defaultUnit; private U defaultUnit;
@Getter @Getter
private final UnitPointerService<U> unitPointerService; private final UnitPointerService unitPointerService;
public AutoResponder(UnitPointerService<U> unitPointerService, Set<U> startUnits) { public AutoResponder(UnitPointerService unitPointerService, Set<U> startUnits) {
this.startUnits = startUnits; this.startUnits = startUnits;
this.unitPointerService = unitPointerService; this.unitPointerService = unitPointerService;
} }
@ -50,20 +49,21 @@ public class AutoResponder<U extends Unit> {
* @param message Запрос пользователя - текстовое сообщение * @param message Запрос пользователя - текстовое сообщение
* @return {@link Unit}, который отвечает за данные для обработки данного запроса * @return {@link Unit}, который отвечает за данные для обработки данного запроса
*/ */
public U answer(@NonNull Integer personId, String message) { public Optional<U> answer(@NonNull Integer personId, String message) {
UnitPointer<U> unitPointer = checkAndAddPerson(personId); Optional<UnitPointer> unitPointer = unitPointerService.getByEntityId(personId);
U unit; Optional<U> unitOpt = nextUnit(
try { !unitPointer.isPresent() || newScenario(unitPointer.get()) ? startUnits : unitPointer.get().getUnit().getNextUnits(),
if (unitPointer.getUnit() == null || unitPointer.getUnit().getNextUnits() == null || unitPointer.getUnit().getNextUnits().isEmpty()) { message
unit = nextUnit(startUnits, message); );
} else { unitOpt.ifPresent(unit -> {
unit = (U) nextUnit(unitPointer.getUnit().getNextUnits(), message); unitPointer.orElseGet(() -> unitPointerService.create(personId));
}
unitPointerService.edit(personId, unit); unitPointerService.edit(personId, unit);
} catch (NotFoundUnitException e) { });
unit = defaultUnit; return unitOpt.isPresent() ? unitOpt : Optional.ofNullable(defaultUnit);
} }
return Optional.ofNullable(unit).orElseThrow(NotFoundUnitException::new);
private boolean newScenario(UnitPointer unitPointer) {
return unitPointer.getUnit() == null || unitPointer.getUnit().getNextUnits() == null || unitPointer.getUnit().getNextUnits().isEmpty();
} }
/** /**
@ -73,7 +73,7 @@ public class AutoResponder<U extends Unit> {
* @param message Запрос пользователя - текстовое сообщение * @param message Запрос пользователя - текстовое сообщение
* @return Юнит, который нуждается в обработке в соответствии с запросом пользователя * @return Юнит, который нуждается в обработке в соответствии с запросом пользователя
*/ */
private U nextUnit(@NonNull Set<U> nextUnits, String message) { private Optional<U> nextUnit(@NonNull Set<U> nextUnits, String message) {
Set<U> searchUnit = new HashSet<>(); Set<U> searchUnit = new HashSet<>();
nextUnits.stream() nextUnits.stream()
@ -97,32 +97,15 @@ public class AutoResponder<U extends Unit> {
.forEach(searchUnit::add); .forEach(searchUnit::add);
} }
return searchUnit.stream().max(unitPriorityComparator).orElseThrow(NotFoundUnitException::new); return searchUnit.stream().max(UNIT_PRIORITY_COMPARATOR);
}
/**
* Проверяет наличие {@link UnitPointer} у пользовтеля и создает его, если не находит
*
* @param personId Идентификатор пользователя
* @return {@link UnitPointer}, который сохраняет {@link Unit}, который был обработан последним
*/
private UnitPointer<U> checkAndAddPerson(@NonNull Integer personId) {
UnitPointer<U> unitPointer;
if (unitPointerService.check(personId)) {
unitPointer = unitPointerService.getByEntityId(personId);
} else {
unitPointer = new UnitPointer<>(personId);
unitPointerService.add(unitPointer);
}
return unitPointer;
} }
private boolean patternReg(@NonNull Unit unit, String message) { private boolean patternReg(@NonNull U unit, String message) {
return message.matches(unit.getPattern().pattern()); return message.matches(unit.getPattern().pattern());
} }
private Double percentageMatch(Unit unit, Set<String> words) { private Double percentageMatch(U unit, Set<String> words) {
if (unit.getKeyWords() != null && !unit.getKeyWords().isEmpty()) { if (unit.getKeyWords() != null && !unit.getKeyWords().isEmpty()) {
Set<String> temp = new HashSet<>(unit.getKeyWords()); Set<String> temp = new HashSet<>(unit.getKeyWords());
temp.retainAll(words); temp.retainAll(words);

View File

@ -9,7 +9,7 @@ import java.util.Comparator;
* *
* @author upagge [07/07/2019] * @author upagge [07/07/2019]
*/ */
public class UnitPriorityComparator<U extends Unit> implements Comparator<U> { public class UnitPriorityComparator implements Comparator<Unit> {
@Override @Override
public int compare(Unit o1, Unit o2) { public int compare(Unit o1, Unit o2) {

View File

@ -39,7 +39,12 @@ public abstract class Unit<U extends Unit> {
@Description("Множество следующих Unit в сценарии") @Description("Множество следующих Unit в сценарии")
protected Set<U> nextUnits; protected Set<U> nextUnits;
protected Unit(Set<String> keyWords, String phrase, Pattern pattern, Integer matchThreshold, Integer priority, Set<U> nextUnits) { protected Unit(Set<String> keyWords,
String phrase,
Pattern pattern,
Integer matchThreshold,
Integer priority,
Set<U> nextUnits) {
this.keyWords = keyWords; this.keyWords = keyWords;
this.phrase = phrase; this.phrase = phrase;
this.pattern = pattern; this.pattern = pattern;

View File

@ -2,6 +2,7 @@ package org.sadtech.autoresponder.entity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.sadtech.autoresponder.util.Description; import org.sadtech.autoresponder.util.Description;
/** /**
@ -10,17 +11,14 @@ import org.sadtech.autoresponder.util.Description;
* @author upagge [07/07/2019] * @author upagge [07/07/2019]
*/ */
@Data @Data
@RequiredArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class UnitPointer<U extends Unit> { public class UnitPointer {
@Description("Идентификатор пользователя") @Description("Идентификатор пользователя")
private Integer entityId; private final Integer entityId;
@Description("Юнит, который был обработан") @Description("Юнит, который был обработан")
private U unit; private Unit unit;
public UnitPointer(Integer entityId) {
this.entityId = entityId;
}
} }

View File

@ -1,29 +1,30 @@
package org.sadtech.autoresponder.repository; package org.sadtech.autoresponder.repository;
import org.sadtech.autoresponder.entity.Unit; import lombok.NonNull;
import org.sadtech.autoresponder.entity.UnitPointer; import org.sadtech.autoresponder.entity.UnitPointer;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
/** /**
* Интегрфейс для работы с хранилищем сущности {@link UnitPointer}. * Интегрфейс для работы с хранилищем сущности {@link UnitPointer}.
* *
* @author upagge [07/07/2019] * @author upagge [07/07/2019]
*/ */
public interface UnitPointerRepository<U extends Unit> { public interface UnitPointerRepository {
void add(UnitPointer<U> unitPointer); UnitPointer add(@NonNull UnitPointer unitPointer);
void edit(UnitPointer<U> unitPointer); void edit(@NonNull UnitPointer unitPointer);
void remove(Integer entityId); void remove(@NonNull Integer entityId);
void addAll(Collection<UnitPointer<U>> unitPointers); void addAll(@NonNull Collection<UnitPointer> unitPointers);
/** /**
* @param entityId Идентификатор пользователя * @param entityId Идентификатор пользователя
* @return Объект с последним обработанным {@link org.sadtech.autoresponder.entity.Unit} для пользователя * @return Объект с последним обработанным {@link org.sadtech.autoresponder.entity.Unit} для пользователя
*/ */
UnitPointer<U> findByEntityId(Integer entityId); Optional<UnitPointer> findByEntityId(@NonNull Integer entityId);
} }

View File

@ -1,29 +1,30 @@
package org.sadtech.autoresponder.repository; package org.sadtech.autoresponder.repository;
import lombok.NonNull; import lombok.NonNull;
import org.sadtech.autoresponder.entity.Unit;
import org.sadtech.autoresponder.entity.UnitPointer; import org.sadtech.autoresponder.entity.UnitPointer;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional;
/** /**
* Реализация хранилища для {@link UnitPointer} на основе Map. * Реализация хранилища для {@link UnitPointer} на основе Map.
* *
* @author upagge [07/07/2019] * @author upagge [07/07/2019]
*/ */
public class UnitPointerRepositoryMap<U extends Unit> implements UnitPointerRepository<U> { public class UnitPointerRepositoryMap implements UnitPointerRepository {
private Map<Integer, UnitPointer<U>> unitPointerMap = new HashMap<>(); private Map<Integer, UnitPointer> unitPointerMap = new HashMap<>();
@Override @Override
public void add(@NonNull UnitPointer<U> unitPointer) { public UnitPointer add(@NonNull UnitPointer unitPointer) {
unitPointerMap.put(unitPointer.getEntityId(), unitPointer); unitPointerMap.put(unitPointer.getEntityId(), unitPointer);
return unitPointer;
} }
@Override @Override
public void edit(@NonNull UnitPointer<U> unitPointer) { public void edit(@NonNull UnitPointer unitPointer) {
unitPointerMap.get(unitPointer.getEntityId()).setUnit(unitPointer.getUnit()); unitPointerMap.get(unitPointer.getEntityId()).setUnit(unitPointer.getUnit());
} }
@ -33,12 +34,12 @@ public class UnitPointerRepositoryMap<U extends Unit> implements UnitPointerRepo
} }
@Override @Override
public void addAll(@NonNull Collection<UnitPointer<U>> unitPointers) { public void addAll(@NonNull Collection<UnitPointer> unitPointers) {
unitPointers.parallelStream().forEach(unitPointer -> unitPointerMap.put(unitPointer.getEntityId(), unitPointer)); unitPointers.parallelStream().forEach(unitPointer -> unitPointerMap.put(unitPointer.getEntityId(), unitPointer));
} }
@Override @Override
public UnitPointer<U> findByEntityId(@NonNull Integer entityId) { public Optional<UnitPointer> findByEntityId(@NonNull Integer entityId) {
return unitPointerMap.get(entityId); return Optional.ofNullable(unitPointerMap.get(entityId));
} }
} }

View File

@ -1,16 +1,19 @@
package org.sadtech.autoresponder.service; package org.sadtech.autoresponder.service;
import lombok.NonNull;
import org.sadtech.autoresponder.entity.Unit; import org.sadtech.autoresponder.entity.Unit;
import org.sadtech.autoresponder.entity.UnitPointer; import org.sadtech.autoresponder.entity.UnitPointer;
import java.util.Optional;
/** /**
* Сервис для взаимодействия с сущностью {@link UnitPointer}. * Сервис для взаимодействия с сущностью {@link UnitPointer}.
* *
* @author upagge [07/07/2019] * @author upagge [07/07/2019]
*/ */
public interface UnitPointerService<U extends Unit> { public interface UnitPointerService {
void add(UnitPointer<U> unitPointer); void add(@NonNull UnitPointer unitPointer);
/** /**
* Проверка наличия {@link UnitPointer} для пользователя * Проверка наличия {@link UnitPointer} для пользователя
@ -18,10 +21,13 @@ public interface UnitPointerService<U extends Unit> {
* @param entityId Идентификатор пользователя * @param entityId Идентификатор пользователя
* @return true - если найдено * @return true - если найдено
*/ */
boolean check(Integer entityId); boolean check(@NonNull Integer entityId);
UnitPointer<U> getByEntityId(Integer entityId); Optional<UnitPointer> getByEntityId(@NonNull Integer entityId);
UnitPointer create(@NonNull Integer entryId);
void edit(@NonNull Integer personId, Unit unit);
void edit(Integer personId, U unit);
} }

View File

@ -1,40 +1,45 @@
package org.sadtech.autoresponder.service; package org.sadtech.autoresponder.service;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.sadtech.autoresponder.entity.Unit; import org.sadtech.autoresponder.entity.Unit;
import org.sadtech.autoresponder.entity.UnitPointer; import org.sadtech.autoresponder.entity.UnitPointer;
import org.sadtech.autoresponder.repository.UnitPointerRepository; import org.sadtech.autoresponder.repository.UnitPointerRepository;
import java.util.Optional;
@Slf4j @Slf4j
public class UnitPointerServiceImpl<U extends Unit> implements UnitPointerService<U> { @RequiredArgsConstructor
public class UnitPointerServiceImpl implements UnitPointerService {
private final UnitPointerRepository<U> unitPointerRepository; private final UnitPointerRepository unitPointerRepository;
public UnitPointerServiceImpl(UnitPointerRepository<U> unitPointerRepository) {
this.unitPointerRepository = unitPointerRepository;
}
@Override @Override
public UnitPointer<U> getByEntityId(@NonNull Integer entityId) { public Optional<UnitPointer> getByEntityId(@NonNull Integer entityId) {
return unitPointerRepository.findByEntityId(entityId); return unitPointerRepository.findByEntityId(entityId);
} }
@Override @Override
public void edit(@NonNull Integer personId, U unit) { public UnitPointer create(@NonNull Integer entryId) {
return unitPointerRepository.add(new UnitPointer(entryId));
}
@Override
public void edit(@NonNull Integer personId, Unit unit) {
if (check(personId)) { if (check(personId)) {
unitPointerRepository.edit(new UnitPointer<>(personId, unit)); unitPointerRepository.edit(new UnitPointer(personId, unit));
} }
} }
@Override @Override
public void add(@NonNull UnitPointer<U> unitPointer) { public void add(@NonNull UnitPointer unitPointer) {
unitPointerRepository.add(unitPointer); unitPointerRepository.add(unitPointer);
log.info("Пользователь отправлен в репозиторий"); log.info("Пользователь отправлен в репозиторий");
} }
@Override @Override
public boolean check(@NonNull Integer entityId) { public boolean check(@NonNull Integer entityId) {
return unitPointerRepository.findByEntityId(entityId) != null; return unitPointerRepository.findByEntityId(entityId).isPresent();
} }
} }

View File

@ -3,13 +3,12 @@ package org.sadtech.autoresponder;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.sadtech.autoresponder.entity.Unit;
import org.sadtech.autoresponder.exception.NotFoundUnitException;
import org.sadtech.autoresponder.repository.UnitPointerRepositoryMap; import org.sadtech.autoresponder.repository.UnitPointerRepositoryMap;
import org.sadtech.autoresponder.service.UnitPointerServiceImpl; import org.sadtech.autoresponder.service.UnitPointerServiceImpl;
import org.sadtech.autoresponder.test.TestUnit; import org.sadtech.autoresponder.test.TestUnit;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -17,7 +16,7 @@ import java.util.stream.Stream;
public class AutoResponderTest { public class AutoResponderTest {
private AutoResponder autoresponder; private AutoResponder<TestUnit> autoresponder;
@Before @Before
public void setUp() { public void setUp() {
@ -60,20 +59,20 @@ public class AutoResponderTest {
.matchThreshold(100) .matchThreshold(100)
.build(); .build();
Set<Unit> testUnits = new HashSet<>(); Set<TestUnit> testUnits = new HashSet<>();
testUnits.add(hello); testUnits.add(hello);
testUnits.add(regExp); testUnits.add(regExp);
testUnits.add(unreal); testUnits.add(unreal);
UnitPointerServiceImpl unitPointerService = new UnitPointerServiceImpl(new UnitPointerRepositoryMap()); UnitPointerServiceImpl unitPointerService = new UnitPointerServiceImpl(new UnitPointerRepositoryMap());
autoresponder = new AutoResponder(unitPointerService, testUnits); autoresponder = new AutoResponder<>(unitPointerService, testUnits);
} }
@Test @Test
public void simpleAnswer() { public void simpleAnswer() {
String message = ((TestUnit) autoresponder.answer(1, "привет это тестирвоание функциональности")).getMessage(); String message = autoresponder.answer(1, "привет это тестирвоание функциональности").get().getMessage();
Assert.assertEquals("тест", message); Assert.assertEquals("тест", message);
String message1 = ((TestUnit) autoresponder.answer(2, "привет, еще одно тестирование")).getMessage(); String message1 = autoresponder.answer(2, "привет, еще одно тестирование").get().getMessage();
Assert.assertEquals("тест", message1); Assert.assertEquals("тест", message1);
} }
@ -82,17 +81,17 @@ public class AutoResponderTest {
TestUnit defaultUnit = TestUnit.builder().message("не знаю").build(); TestUnit defaultUnit = TestUnit.builder().message("не знаю").build();
autoresponder.setDefaultUnit(defaultUnit); autoresponder.setDefaultUnit(defaultUnit);
Assert.assertEquals("не знаю", ((TestUnit) autoresponder.answer(2, "пока")).getMessage()); Assert.assertEquals("не знаю", autoresponder.answer(2, "пока").get().getMessage());
} }
@Test(expected = NotFoundUnitException.class) @Test
public void notDefaultAnswer() { public void notDefaultAnswer() {
autoresponder.answer(2, "пока"); Assert.assertEquals(Optional.empty(), autoresponder.answer(2, "пока"));
} }
@Test @Test
public void regExpAnswer() { public void regExpAnswer() {
String message = ((TestUnit) autoresponder.answer(1, "79101234567")).getMessage(); String message = autoresponder.answer(1, "79101234567").get().getMessage();
Assert.assertEquals("регулярка", message); Assert.assertEquals("регулярка", message);
} }
@ -100,9 +99,9 @@ public class AutoResponderTest {
public void priorityAnswer() { public void priorityAnswer() {
autoresponder.answer(1, "привет"); autoresponder.answer(1, "привет");
autoresponder.answer(2, "привет"); autoresponder.answer(2, "привет");
String message = ((TestUnit) autoresponder.answer(1, "как твои делишки")).getMessage(); String message = autoresponder.answer(1, "как твои делишки").get().getMessage();
Assert.assertEquals("отлично", message); Assert.assertEquals("отлично", message);
String message1 = ((TestUnit) autoresponder.answer(2, "твои дела все еще хорошо?")).getMessage(); String message1 = autoresponder.answer(2, "твои дела все еще хорошо?").get().getMessage();
Assert.assertEquals("хорошо", message1); Assert.assertEquals("хорошо", message1);
} }
@ -110,14 +109,14 @@ public class AutoResponderTest {
public void showRegExpVsKeyWords() { public void showRegExpVsKeyWords() {
autoresponder.answer(1, "привет"); autoresponder.answer(1, "привет");
autoresponder.answer(1, "дела"); autoresponder.answer(1, "дела");
Assert.assertEquals("регулярка", ((TestUnit) autoresponder.answer(1, "89101234567")).getMessage()); Assert.assertEquals("регулярка", autoresponder.answer(1, "89101234567").get().getMessage());
} }
@Test(expected = NotFoundUnitException.class) @Test
public void matchThreshold() { public void matchThreshold() {
autoresponder.answer(1, "витамин я сьем, и арбуз получу"); autoresponder.answer(1, "витамин я сьем, и арбуз получу");
String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт"; String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт";
String answer = ((TestUnit) autoresponder.answer(1, message)).getMessage(); String answer = autoresponder.answer(1, message).get().getMessage();
Assert.assertEquals("победа", answer); Assert.assertEquals("победа", answer);
} }
@ -125,16 +124,16 @@ public class AutoResponderTest {
public void generalAnswer() { public void generalAnswer() {
TestUnit defaultUnit = TestUnit.builder().message("не знаю").build(); TestUnit defaultUnit = TestUnit.builder().message("не знаю").build();
autoresponder.setDefaultUnit(defaultUnit); autoresponder.setDefaultUnit(defaultUnit);
String answer = ((TestUnit) autoresponder.answer(1, "привет это тестирование функциональности")).getMessage(); String answer = autoresponder.answer(1, "привет это тестирование функциональности").get().getMessage();
Assert.assertEquals("тест", answer); Assert.assertEquals("тест", answer);
Assert.assertEquals("хорошо", ((TestUnit) autoresponder.answer(1, "как твои дела")).getMessage()); Assert.assertEquals("хорошо", autoresponder.answer(1, "как твои дела").get().getMessage());
String answer2 = ((TestUnit) autoresponder.answer(2, "привет это тестирование функциональности")).getMessage(); String answer2 = autoresponder.answer(2, "привет это тестирование функциональности").get().getMessage();
Assert.assertEquals("тест", answer2); Assert.assertEquals("тест", answer2);
Assert.assertEquals("не знаю", ((TestUnit) autoresponder.answer(1, "нет")).getMessage()); Assert.assertEquals("не знаю", autoresponder.answer(1, "нет").get().getMessage());
String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт"; String message = "параметр себе задам: покушать витамин и арбуз, а вместе все это мультифрукт";
Assert.assertEquals("победа", ((TestUnit) autoresponder.answer(3, message)).getMessage()); Assert.assertEquals("победа", autoresponder.answer(3, message).get().getMessage());
Assert.assertEquals("регулярка", ((TestUnit) autoresponder.answer(1, "8912345678")).getMessage()); Assert.assertEquals("регулярка", autoresponder.answer(1, "8912345678").get().getMessage());
String answer3 = ((TestUnit) autoresponder.answer(1, "привет это тестирование функциональности")).getMessage(); String answer3 = autoresponder.answer(1, "привет это тестирование функциональности").get().getMessage();
Assert.assertEquals("тест", answer3); Assert.assertEquals("тест", answer3);
} }

View File

@ -13,7 +13,7 @@ import java.util.regex.Pattern;
@Getter @Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString @ToString
public class TestUnit extends Unit { public class TestUnit extends Unit<TestUnit> {
private String message; private String message;
@ -23,7 +23,7 @@ public class TestUnit extends Unit {
Pattern pattern, Pattern pattern,
Integer matchThreshold, Integer matchThreshold,
Integer priority, Integer priority,
@Singular Set<Unit> nextUnits, @Singular Set<TestUnit> nextUnits,
String message) { String message) {
super(keyWords, phrase, pattern, matchThreshold, priority, nextUnits); super(keyWords, phrase, pattern, matchThreshold, priority, nextUnits);
this.message = message; this.message = message;