net.gdface.facelog.FuzzyMatchManagement Maven / Gradle / Ivy
package net.gdface.facelog;
import java.util.List;
import java.util.Map.Entry;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import gu.sql2java.IFuzzyMatchFilter.MatchErrorHandler;
import gu.sql2java.BaseBean;
import gu.sql2java.ColumnGetter;
import gu.sql2java.IStringMatchFilter;
import gu.sql2java.StringFieldSearcher;
import gu.sql2java.StringMatchType;
import gu.sql2java.TableManager;
import net.gdface.facelog.db.DeviceBean;
import net.gdface.facelog.db.DeviceGroupBean;
import net.gdface.facelog.db.IDeviceGroupManager;
import net.gdface.facelog.db.IPersonGroupManager;
import net.gdface.facelog.db.IDeviceManager;
import net.gdface.facelog.db.IPersonManager;
import net.gdface.facelog.db.PersonBean;
import net.gdface.facelog.db.PersonGroupBean;
import net.gdface.utils.BeanRelativeUtilits;
import net.gdface.utils.ConditionChecks;
import static net.gdface.facelog.db.Constant.FL_PERSON_ID_MOBILE_PHONE;
import static net.gdface.facelog.db.Constant.FL_PERSON_ID_PAPERS_NUM;
import static net.gdface.facelog.db.Constant.FL_DEVICE_ID_MAC;
/**
* 模糊查询
* @author guyadong
*
*/
class FuzzyMatchManagement implements MatchErrorHandler,ServiceConstant{
private final DaoManagement dm;
/**
* 设备组模糊匹配对象
*/
private final GroupMatcher deviceGroupMatcher;
/**
* 人员组模糊匹配对象
*/
private final GroupMatcher personGroupMatcher;
/**
* 设备名字模糊匹配对象
*/
private final NameMatcher deviceNameMatcher;
/**
* 设备MAC地址模糊匹配对象
*/
private final DeviceMacMatcher deviceMacMatcher;
/**
* 人员名字模糊匹配对象
*/
private final NameMatcher personNameMatcher;
/**
* 人员移动手机号模糊匹配对象
*/
private final PersonMobilePhoneMatcher mobilePhoneMatcher;
/**
* 人员证件号码模糊匹配对象
*/
private final PersonPapersNumMatcher papersNumMatcher;
FuzzyMatchManagement(DaoManagement dm) {
this.dm = dm;
this.deviceGroupMatcher = new GroupMatcher<>(IDeviceGroupManager.class);
this.personGroupMatcher = new GroupMatcher<>(IPersonGroupManager.class);
this.personNameMatcher = new NameMatcher<>(IPersonManager.class);
this.deviceNameMatcher = new NameMatcher<>(IDeviceManager.class);
this.mobilePhoneMatcher = new PersonMobilePhoneMatcher();
this.papersNumMatcher = new PersonPapersNumMatcher();
this.deviceMacMatcher = new DeviceMacMatcher();
}
FuzzyMatchManagement init(){
logger.info("Device group fuzzy matcher initializing");
deviceGroupMatcher.init();
logger.info("Person group fuzzy matcher initializing");
personGroupMatcher.init();
logger.info("Device name fuzzy matcher initializing");
deviceNameMatcher.init();
logger.info("Device mac fuzzy matcher initializing");
deviceMacMatcher.init();
logger.info("Person name fuzzy matcher initializing");
personNameMatcher.init();
logger.info("Person mobile phone fuzzy matcher initializing");
mobilePhoneMatcher.init();
logger.info("Person papersnum matcher initializing");
papersNumMatcher.init();
return this;
}
/**
* 表字段模糊匹配查询
* 根据指定的匹配条件({@code pattern})对{@code tablename}指定的表字段模糊匹配
* 比如 '1102'匹配'1楼/1单元/102室'
* {@code column} 取值与{@code tablename}的值相关
*
* tablename值 -- column可取值
* fl_device -- name,mac
* fl_person -- name,papsers_num,mobile_phone
* fl_device_group -- 忽略
* fl_person_group-- 忽略
*
* {@code matchType}为{@code null}时,使用的默认匹配策略与{@code tablename}和{@code column}相关
*
* tablename,column值--默认匹配策略
* fl_device.name--支持通配符的字符串比较匹配{@link StringMatchType#WILDCARD_MATCH}
* fl_device.mac--支持通配符的字符串比较匹配{@link StringMatchType#WILDCARD_MATCH}
* fl_person.name--支持通配符的字符串比较匹配{@link StringMatchType#WILDCARD_MATCH}
* fl_person.papsers_num--支持通配符的字符串比较匹配{@link StringMatchType#WILDCARD_MATCH}
* fl_person.mobile_phone--数字模糊匹配{@link StringMatchType#DIGIT_FUZZY_MATCH}
* fl_device_group--右侧数字模糊匹配{@link StringMatchType#DIGIT_FUZZY_RIGHT_MATCH}
* fl_person_group--右侧数字模糊匹配{@link StringMatchType#DIGIT_FUZZY_RIGHT_MATCH}
*
* @param tablename 表名,必须为'fl_device_group'或'fl_person_group','fl_device','fl_person'
* @param column 指定模糊搜索的表字段名,可为{@code null}
* @param pattern 模糊匹配条件,如'102'
* @param matchType 模糊匹配策略,为{@code null}使用默认值
* @param maxMatchCount 要求的最多匹配结果,如果返回的匹配结果超过此值则抛出异常,小于等于0时忽略
* @return 匹配结果列表,没有找到匹配记录时返回空表
* @throws FuzzyMatchCountExceedLimitException 返回的匹配结果超过{@code maxMatchCount}
*/
List fuzzySearch(String tablename,String column,String pattern, StringMatchType matchType, int maxMatchCount)
throws FuzzyMatchCountExceedLimitException{
List matched;
if(deviceNameMatcher.equals(column)){
if(deviceNameMatcher.getEffectColumnName().equals(column)){
matched = deviceNameMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else if(deviceMacMatcher.getEffectColumnName().equals(column)){
matched = deviceMacMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else{
throw new IllegalArgumentException("INVALID column " + column);
}
}else if(personNameMatcher.equals(column)){
if(personNameMatcher.getEffectColumnName().equals(column)){
matched = personNameMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else if(mobilePhoneMatcher.getEffectColumnName().equals(column)){
matched = mobilePhoneMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else if(papersNumMatcher.getEffectColumnName().equals(column)){
matched = papersNumMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else{
throw new IllegalArgumentException("INVALID column " + column);
}
}else if(deviceGroupMatcher.getTablename().equals(tablename)){
matched = deviceGroupMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else if(personGroupMatcher.getTablename().equals(tablename)){
matched = personGroupMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else if(deviceNameMatcher.getTablename().equals(tablename)){
matched = deviceNameMatcher.fuzzySearch(pattern, matchType == null ? null : matchType.createMatchFilter());
}else{
throw new IllegalArgumentException("INVALID tablename " + tablename);
}
ConditionChecks.checkTrue(maxMatchCount <= 0 || matched.size() <= maxMatchCount,
FuzzyMatchCountExceedLimitException.class,
"too manay match count %s, exceed max limit %s",matched.size(),maxMatchCount);
return matched;
}
@Override
public void onMatchError(Throwable e, String pattern) {
logger.error("pattern={},{}:{}",pattern,e.getClass().getSimpleName(),e.getMessage());
}
protected static class StringFieldSearcherForMatchEntry extends StringFieldSearcher{
public > StringFieldSearcherForMatchEntry(Class interfaceClass,
String... effectColumnNames) {
super(interfaceClass, effectColumnNames);
}
public > StringFieldSearcherForMatchEntry(Class interfaceClass,
int... effectColumnId) {
super(interfaceClass, effectColumnId);
}
public final List fuzzySearch(String pattern, IStringMatchFilter matchFilter){
Multimap mm = super.search(pattern, matchFilter);
List entrys = Lists.newArrayList();
for(Entry entry:mm.entries()){
entrys.add(new MatchEntry(entry.getValue(), entry.getKey()));
}
// 按匹配的名字排序
return BeanRelativeUtilits.sortByField(entrys, "key");
}
}
/**
* 设备组/人员组路径模糊匹配对象
* 默认使用'右侧数字模糊匹配'匹配策略
* @author guyadong
*
* @param 表记录类型
* @param 表访问实例类型
*/
private class GroupMatcher > extends StringFieldSearcherForMatchEntry{
public GroupMatcher(Class interfaceClass) {
super(interfaceClass, "name","parent");
setDefaultMatchFilter(StringMatchType.DIGIT_FUZZY_RIGHT_MATCH);
setFunKeyGetter(new GroupPathGetter<>(interfaceClass));
setErrorHandler(FuzzyMatchManagement.this);
}
}
/**
* 设备/人员名字{@code name}字段模糊匹配对象
* 默认使用'支持通配符的字符串比较匹配'匹配策略
* @author guyadong
*
* @param 表记录类型
* @param 表访问实例类型
*/
private class NameMatcher > extends StringFieldSearcherForMatchEntry{
@SuppressWarnings("unchecked")
public NameMatcher(Class interfaceClass) {
super(interfaceClass, "name");
setDefaultMatchFilter(StringMatchType.WILDCARD_MATCH);
setFunKeyGetter((Function) new ColumnGetter("name"));
setErrorHandler(FuzzyMatchManagement.this);
}
}
private class PersonMobilePhoneMatcher extends StringFieldSearcherForMatchEntry{
@SuppressWarnings("unchecked")
public PersonMobilePhoneMatcher() {
super(IPersonManager.class, FL_PERSON_ID_MOBILE_PHONE);
setDefaultMatchFilter(StringMatchType.DIGIT_FUZZY_MATCH);
Function extends BaseBean, String> f = new ColumnGetter(FL_PERSON_ID_MOBILE_PHONE);
setFunKeyGetter((Function) f);
setErrorHandler(FuzzyMatchManagement.this);
}
}
private class PersonPapersNumMatcher extends StringFieldSearcherForMatchEntry{
@SuppressWarnings("unchecked")
public PersonPapersNumMatcher() {
super(IPersonManager.class, FL_PERSON_ID_PAPERS_NUM);
setDefaultMatchFilter(StringMatchType.WILDCARD_MATCH);
Function extends BaseBean, String> f = new ColumnGetter(FL_PERSON_ID_PAPERS_NUM);
setFunKeyGetter((Function) f);
setErrorHandler(FuzzyMatchManagement.this);
}
}
private class DeviceMacMatcher extends StringFieldSearcherForMatchEntry{
@SuppressWarnings("unchecked")
public DeviceMacMatcher() {
super(IDeviceManager.class, FL_DEVICE_ID_MAC);
setDefaultMatchFilter(StringMatchType.WILDCARD_MATCH);
Function extends BaseBean, String> f = new ColumnGetter(FL_DEVICE_ID_MAC);
setFunKeyGetter((Function) f);
setErrorHandler(FuzzyMatchManagement.this);
}
}
private class GroupPathGetter> implements Function{
private final Class interfaceClass;
public GroupPathGetter(Class interfaceClass) {
this.interfaceClass = interfaceClass;
}
@Override
public String apply(B input) {
return dm.daoGroupPathOf(interfaceClass,input);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy