package com.walker.tcp;
import com.walker.tcp.protocol.StringProtocolResolver;
import com.walker.tcp.util.ConvertorUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 集中存放系统定义的所有ProtocolResolver
对象。
* 注意:一定要把默认的回车换行的ProtocolResolver配置在最后面,因为有可能其他特殊前缀的报文也会使用回车换行结尾,
* 因此如果出现这种情况,也能确保用户自定义的ProtocolResolver会优先被调用。
* @author 时克英
* @date 2018-11-27
*
*/
public class ProtocolResolverPostProcessor implements BeanPostProcessor {
private final transient Log logger = LogFactory.getLog(getClass());
private static final Map> reference = new HashMap>();
private static List> cacheList =null;
private final InnerComparator comparator = new InnerComparator();
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if(ProtocolResolver.class.isAssignableFrom(bean.getClass())){
ProtocolResolver> pr = (ProtocolResolver>)bean;
if(cacheList == null){
cacheList = new ArrayList<>(4);
}
if(isDuplicateOrder(pr.getOrder())){
throw new IllegalArgumentException("已经存在相同序号的ProtocolResolver对象,order = " + pr.getOrder());
}
cacheList.add(pr);
reference.put(pr.getOrder(), pr);
logger.info("找到了一个ProtocolResolver:" + pr.getName());
// 这里必须排序
Collections.sort(cacheList, comparator);
}
return bean;
}
/**
* 是否存在重复order
* @param order
* @return
*/
private boolean isDuplicateOrder(int order){
for(ProtocolResolver> pr : cacheList){
if(order >= 0 && order == pr.getOrder()){
return true;
}
}
return false;
}
/**
* 根据唯一排序号,查找对应的解析器对象。
* 该方法在使用request时使用,因为之前是把resolver放到request对象中关联,但在request序列化问题中不好处理,所以只存放order即可。
* @param order 排序号,该数值唯一
* @return
*/
public static final ProtocolResolver> getProtocolResolver(int order){
ProtocolResolver> pr = reference.get(order);
if(pr == null){
throw new IllegalArgumentException(ProtocolResolver.ERR_NOFOUND);
}
return pr;
}
/**
* 根据报文内容,找到使用的协议解析器。
* 目前系统根据后缀来查找。
* 该方法在老的对象中使用:LongHandler
* @param message
* @return
*/
public static final StringProtocolResolver getProtocolResolver(String message){
if(cacheList == null){
throw new IllegalArgumentException(ProtocolResolver.ERR_NOFOUND);
}
return (StringProtocolResolver)ConvertorUtils.getProtocolResolver(message, cacheList);
}
/**
* 返回系统定义的所有ProtocolResolver
对象集合
* @return
*/
public static List> getProtocolResolverList(){
return cacheList;
}
private static class InnerComparator implements Comparator>{
@Override
public int compare(ProtocolResolver> o1, ProtocolResolver> o2) {
return o1.getOrder() - o2.getOrder();
}
}
public static void testAddResolver(ProtocolResolver> pr){
if(cacheList == null){
cacheList = new ArrayList<>(4);
}
cacheList.add(pr);
reference.put(pr.getOrder(), pr);
// 这里必须排序
Collections.sort(cacheList, new InnerComparator());
}
}