Merge branch 'release/release-1.6.0'
This commit is contained in:
commit
2c2547013b
10
pom.xml
10
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>org.sadtech.autoresponder</groupId>
|
<groupId>org.sadtech.autoresponder</groupId>
|
||||||
<artifactId>autoresponder</artifactId>
|
<artifactId>autoresponder</artifactId>
|
||||||
<version>1.5.0-RELEASE</version>
|
<version>1.6.0-RELEASE</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
@ -23,14 +23,14 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<log4j>1.2.17</log4j>
|
<slf4j.ver>1.7.26</slf4j.ver>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>${log4j}</version>
|
<version>${slf4j.ver}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package org.sadtech.autoresponder;
|
package org.sadtech.autoresponder;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.sadtech.autoresponder.compare.UnitPriorityComparator;
|
import org.sadtech.autoresponder.compare.UnitPriorityComparator;
|
||||||
import org.sadtech.autoresponder.entity.UnitPointer;
|
|
||||||
import org.sadtech.autoresponder.entity.Unit;
|
import org.sadtech.autoresponder.entity.Unit;
|
||||||
|
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.Parser;
|
import org.sadtech.autoresponder.util.Parser;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -13,79 +15,76 @@ import java.util.Set;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Отвечает за функционирование автоответчика
|
||||||
|
*/
|
||||||
public class Autoresponder {
|
public class Autoresponder {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(Autoresponder.class);
|
private static final Logger log = LoggerFactory.getLogger(Autoresponder.class);
|
||||||
|
private static final UnitPriorityComparator UNIT_PRIORITY_COMPARATOR = new UnitPriorityComparator();
|
||||||
|
|
||||||
private Set<Unit> menuUnits;
|
private final Set<Unit> startUnits;
|
||||||
private UnitPointerService unitPointerService;
|
private Unit defaultUnit;
|
||||||
|
private final UnitPointerService unitPointerService;
|
||||||
|
|
||||||
public Autoresponder(UnitPointerService unitPointerService) {
|
public Autoresponder(UnitPointerService unitPointerService, Set<Unit> startUnits) {
|
||||||
|
this.startUnits = startUnits;
|
||||||
this.unitPointerService = unitPointerService;
|
this.unitPointerService = unitPointerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMenuUnits(Set<Unit> menuUnits) {
|
|
||||||
this.menuUnits = menuUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnitPointerService getUnitPointerService() {
|
public UnitPointerService getUnitPointerService() {
|
||||||
return unitPointerService;
|
return unitPointerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnitPointerService(UnitPointerService unitPointerService) {
|
public void setDefaultUnit(Unit defaultUnit) {
|
||||||
this.unitPointerService = unitPointerService;
|
this.defaultUnit = defaultUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Unit answer(Integer idPerson, String message) {
|
public Unit answer(Integer personId, String message) {
|
||||||
UnitPointer unitPointer = checkAndAddPerson(idPerson);
|
UnitPointer unitPointer = checkAndAddPerson(personId);
|
||||||
Unit unit;
|
Unit unit;
|
||||||
if (unitPointer.getUnit() == null) {
|
try {
|
||||||
unit = nextUnit(menuUnits, message);
|
if (unitPointer.getUnit() == null || unitPointer.getUnit().getNextUnits() == null) {
|
||||||
} else {
|
unit = nextUnit(startUnits, message); // выбирает unit из startUnits, если пользователь обращается впервые
|
||||||
if (unitPointer.getUnit().getNextUnits() == null) {
|
|
||||||
unit = nextUnit(menuUnits, message);
|
|
||||||
} else {
|
} else {
|
||||||
unit = nextUnit(unitPointer.getUnit().getNextUnits(), message);
|
unit = nextUnit(unitPointer.getUnit().getNextUnits(), message);
|
||||||
}
|
}
|
||||||
|
unitPointerService.edit(personId, unit);
|
||||||
|
} catch (NotFoundUnitException e) {
|
||||||
|
unit = defaultUnit;
|
||||||
}
|
}
|
||||||
if (unit != null) {
|
return Optional.ofNullable(unit).orElseThrow(NotFoundUnitException::new);
|
||||||
unitPointer.setUnit(unit);
|
|
||||||
}
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UnitPointer checkAndAddPerson(Integer idPerson) {
|
|
||||||
UnitPointer unitPointer;
|
|
||||||
if (unitPointerService.check(idPerson)) {
|
|
||||||
unitPointer = unitPointerService.getByEntityId(idPerson);
|
|
||||||
} else {
|
|
||||||
unitPointer = new UnitPointer(idPerson);
|
|
||||||
unitPointerService.add(unitPointer);
|
|
||||||
}
|
|
||||||
return unitPointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Unit nextUnit(Set<Unit> nextUnits, String message) {
|
private Unit nextUnit(Set<Unit> nextUnits, String message) {
|
||||||
if (nextUnits.size() > 0) {
|
Optional<Unit> unit = nextUnits.stream()
|
||||||
UnitPriorityComparator unitPriorityComparator = new UnitPriorityComparator();
|
.filter(nextUnit -> nextUnit.getPattern() != null)
|
||||||
Optional<Unit> patternUnits = nextUnits.stream().filter(nextUnit -> nextUnit.getPattern() != null).filter(nextUnit -> patternReg(nextUnit, message)).max(unitPriorityComparator);
|
.filter(nextUnit -> patternReg(nextUnit, message))
|
||||||
|
.max(UNIT_PRIORITY_COMPARATOR);
|
||||||
|
|
||||||
if (!patternUnits.isPresent()) {
|
if (!unit.isPresent()) {
|
||||||
patternUnits = nextUnits.stream()
|
unit = nextUnits.stream()
|
||||||
.filter(nextUnit -> textPercentageMatch(nextUnit, Parser.parse(message)) >= nextUnit.getMatchThreshold())
|
.filter(nextUnit -> textPercentageMatch(nextUnit, Parser.parse(message)) >= nextUnit.getMatchThreshold())
|
||||||
.max(unitPriorityComparator);
|
.max(UNIT_PRIORITY_COMPARATOR);
|
||||||
}
|
|
||||||
|
|
||||||
if (!patternUnits.isPresent()) {
|
|
||||||
patternUnits = nextUnits.stream()
|
|
||||||
.filter(nextUnit -> (nextUnit.getPattern() == null && nextUnit.getKeyWords() == null))
|
|
||||||
.max(unitPriorityComparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
return patternUnits.orElse(null);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!unit.isPresent()) {
|
||||||
|
unit = nextUnits.stream()
|
||||||
|
.filter(nextUnit -> (nextUnit.getPattern() == null && nextUnit.getKeyWords() == null))
|
||||||
|
.max(UNIT_PRIORITY_COMPARATOR);
|
||||||
|
}
|
||||||
|
return unit.orElseThrow(NotFoundUnitException::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UnitPointer checkAndAddPerson(Integer personId) {
|
||||||
|
UnitPointer unitPointer;
|
||||||
|
if (unitPointerService.check(personId)) {
|
||||||
|
unitPointer = unitPointerService.getByEntityId(personId);
|
||||||
|
} else {
|
||||||
|
unitPointer = new UnitPointer(personId);
|
||||||
|
unitPointerService.add(unitPointer);
|
||||||
|
}
|
||||||
|
return unitPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean patternReg(Unit unit, String message) {
|
private boolean patternReg(Unit unit, String message) {
|
||||||
@ -98,7 +97,6 @@ public class Autoresponder {
|
|||||||
if (unit.getKeyWords() != null) {
|
if (unit.getKeyWords() != null) {
|
||||||
Set<String> temp = new HashSet<>(unit.getKeyWords());
|
Set<String> temp = new HashSet<>(unit.getKeyWords());
|
||||||
temp.retainAll(words);
|
temp.retainAll(words);
|
||||||
log.info("Юнит: " + unit.getClass().getSimpleName());
|
|
||||||
log.info("Ключевые слова юнита: " + unit.getKeyWords() + " (" + unit.getKeyWords().size() + ")");
|
log.info("Ключевые слова юнита: " + unit.getKeyWords() + " (" + unit.getKeyWords().size() + ")");
|
||||||
log.info("Ключевые слова от пользователя: " + words);
|
log.info("Ключевые слова от пользователя: " + words);
|
||||||
log.info("Пересечение: " + temp + " (" + temp.size() + ")");
|
log.info("Пересечение: " + temp + " (" + temp.size() + ")");
|
||||||
|
@ -1,51 +1,56 @@
|
|||||||
package org.sadtech.autoresponder.entity;
|
package org.sadtech.autoresponder.entity;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Абстрактный класс, предпологающий какие-то действия
|
||||||
|
*/
|
||||||
public abstract class Unit {
|
public abstract class Unit {
|
||||||
|
|
||||||
private Set<String> keyWords;
|
private Set<String> keyWords;
|
||||||
private Pattern pattern;
|
private Pattern pattern;
|
||||||
private Integer matchThreshold;
|
private Integer matchThreshold = 10;
|
||||||
private Integer priority;
|
private Integer priority = 10;
|
||||||
private Set<Unit> nextUnits;
|
private Set<Unit> nextUnits;
|
||||||
|
|
||||||
public Unit() {
|
public void setKeyWord(String... keyWord) {
|
||||||
priority = 10;
|
if (this.keyWords == null) {
|
||||||
matchThreshold = 10;
|
this.keyWords = new HashSet<>();
|
||||||
}
|
|
||||||
|
|
||||||
public Unit(Set<String> keyWords, Pattern pattern, Integer matchThreshold, Integer priority, Set<Unit> nextUnits) {
|
|
||||||
this.keyWords = keyWords;
|
|
||||||
this.pattern = pattern;
|
|
||||||
this.matchThreshold = matchThreshold;
|
|
||||||
this.priority = priority;
|
|
||||||
this.nextUnits = nextUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyWord(String keyWord) {
|
|
||||||
if (keyWords == null) {
|
|
||||||
keyWords = new HashSet<>();
|
|
||||||
}
|
}
|
||||||
keyWords.add(keyWord);
|
this.keyWords.addAll(Arrays.asList(keyWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNextUnit(Unit unit) {
|
public void setKeyWords(Set<String> keyWords) {
|
||||||
if (nextUnits == null) {
|
if (this.keyWords == null) {
|
||||||
nextUnits = new HashSet<>();
|
this.keyWords = new HashSet<>();
|
||||||
}
|
}
|
||||||
nextUnits.add(unit);
|
this.keyWords.addAll(keyWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getKeyWords() {
|
public Set<String> getKeyWords() {
|
||||||
return keyWords;
|
return keyWords;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyWords(Set<String> keyWords) {
|
public void setNextUnit(Unit... unit) {
|
||||||
this.keyWords = keyWords;
|
if (nextUnits == null) {
|
||||||
|
nextUnits = new HashSet<>();
|
||||||
|
}
|
||||||
|
nextUnits.addAll(Arrays.asList(unit));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNextUnits(Set<Unit> nextUnits) {
|
||||||
|
if (nextUnits == null) {
|
||||||
|
nextUnits = new HashSet<>();
|
||||||
|
}
|
||||||
|
this.nextUnits.addAll(nextUnits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Unit> getNextUnits() {
|
||||||
|
return nextUnits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getMatchThreshold() {
|
public Integer getMatchThreshold() {
|
||||||
@ -64,14 +69,6 @@ public abstract class Unit {
|
|||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Unit> getNextUnits() {
|
|
||||||
return nextUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNextUnits(Set<Unit> nextUnits) {
|
|
||||||
this.nextUnits = nextUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pattern getPattern() {
|
public Pattern getPattern() {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
@ -83,7 +80,7 @@ public abstract class Unit {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (!(o instanceof Unit)) return false;
|
||||||
Unit unit = (Unit) o;
|
Unit unit = (Unit) o;
|
||||||
return Objects.equals(keyWords, unit.keyWords) &&
|
return Objects.equals(keyWords, unit.keyWords) &&
|
||||||
Objects.equals(pattern, unit.pattern) &&
|
Objects.equals(pattern, unit.pattern) &&
|
||||||
|
@ -2,6 +2,9 @@ package org.sadtech.autoresponder.entity;
|
|||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Сохраняет юнит, на котором остановился пользователь.
|
||||||
|
*/
|
||||||
public class UnitPointer {
|
public class UnitPointer {
|
||||||
|
|
||||||
private Integer entityId;
|
private Integer entityId;
|
||||||
@ -45,4 +48,12 @@ public class UnitPointer {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(entityId, unit);
|
return Objects.hash(entityId, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UnitPointer{" +
|
||||||
|
"entityId=" + entityId +
|
||||||
|
", unit=" + unit +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package org.sadtech.autoresponder.exception;
|
||||||
|
|
||||||
|
public class NotFoundUnitException extends RuntimeException {
|
||||||
|
}
|
@ -8,6 +8,8 @@ public interface UnitPointerRepository {
|
|||||||
|
|
||||||
Integer add(UnitPointer unitPointer);
|
Integer add(UnitPointer unitPointer);
|
||||||
|
|
||||||
|
void edit(UnitPointer unitPointer);
|
||||||
|
|
||||||
void remove(Integer entityId);
|
void remove(Integer entityId);
|
||||||
|
|
||||||
void addAll(Map<Integer, UnitPointer> unitPointerMap);
|
void addAll(Map<Integer, UnitPointer> unitPointerMap);
|
||||||
|
@ -15,6 +15,11 @@ public class UnitPointerRepositoryMap implements UnitPointerRepository {
|
|||||||
return unitPointer.getEntityId();
|
return unitPointer.getEntityId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void edit(UnitPointer unitPointer) {
|
||||||
|
unitPointerMap.get(unitPointer.getEntityId()).setUnit(unitPointer.getUnit());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(Integer entityId) {
|
public void remove(Integer entityId) {
|
||||||
unitPointerMap.remove(entityId);
|
unitPointerMap.remove(entityId);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.sadtech.autoresponder.service;
|
package org.sadtech.autoresponder.service;
|
||||||
|
|
||||||
|
import org.sadtech.autoresponder.entity.Unit;
|
||||||
import org.sadtech.autoresponder.entity.UnitPointer;
|
import org.sadtech.autoresponder.entity.UnitPointer;
|
||||||
|
|
||||||
public interface UnitPointerService {
|
public interface UnitPointerService {
|
||||||
@ -10,4 +11,6 @@ public interface UnitPointerService {
|
|||||||
|
|
||||||
UnitPointer getByEntityId(Integer entityId);
|
UnitPointer getByEntityId(Integer entityId);
|
||||||
|
|
||||||
|
void edit(Integer personId, Unit unit);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package org.sadtech.autoresponder.service;
|
package org.sadtech.autoresponder.service;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
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 org.sadtech.autoresponder.repository.UnitPointerRepositoryMap;
|
import org.sadtech.autoresponder.repository.UnitPointerRepositoryMap;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class UnitPointerServiceImpl implements UnitPointerService {
|
public class UnitPointerServiceImpl implements UnitPointerService {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(UnitPointerServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(UnitPointerServiceImpl.class);
|
||||||
|
|
||||||
private UnitPointerRepository unitPointerRepository;
|
private UnitPointerRepository unitPointerRepository;
|
||||||
|
|
||||||
@ -24,6 +26,13 @@ public class UnitPointerServiceImpl implements UnitPointerService {
|
|||||||
return unitPointerRepository.findByEntityId(entityId);
|
return unitPointerRepository.findByEntityId(entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void edit(Integer personId, Unit unit) {
|
||||||
|
if (check(personId)) {
|
||||||
|
unitPointerRepository.edit(new UnitPointer(personId, unit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(UnitPointer unitPointer) {
|
public void add(UnitPointer unitPointer) {
|
||||||
unitPointerRepository.add(unitPointer);
|
unitPointerRepository.add(unitPointer);
|
||||||
|
@ -4,9 +4,19 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Возвращает Set слов из текста
|
||||||
|
*/
|
||||||
public class Parser {
|
public class Parser {
|
||||||
|
|
||||||
|
private static final Set<String> pretexts = Stream
|
||||||
|
.of("в", "без", "до", "из", "к", "на", "по", "о", "от", "перед", "при", "с", "у", "за", "над", "об",
|
||||||
|
"под", "про", "для")
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
private Parser() {
|
private Parser() {
|
||||||
throw new IllegalStateException("Utility Class");
|
throw new IllegalStateException("Utility Class");
|
||||||
}
|
}
|
||||||
@ -18,6 +28,7 @@ public class Parser {
|
|||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
words.add(m.group().toLowerCase());
|
words.add(m.group().toLowerCase());
|
||||||
}
|
}
|
||||||
|
words.removeAll(pretexts);
|
||||||
return words;
|
return words;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user