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;
|
|
/**
|
* 集中存放系统定义的所有<code>ProtocolResolver</code>对象。</p>
|
* 注意:一定要把默认的回车换行的ProtocolResolver配置在最后面,因为有可能其他特殊前缀的报文也会使用回车换行结尾,
|
* 因此如果出现这种情况,也能确保用户自定义的ProtocolResolver会优先被调用。
|
* @author 时克英
|
* @date 2018-11-27
|
*
|
*/
|
public class ProtocolResolverPostProcessor implements BeanPostProcessor {
|
|
private final transient Log logger = LogFactory.getLog(getClass());
|
|
private static final Map<Integer, ProtocolResolver<?>> reference = new HashMap<Integer, ProtocolResolver<?>>();
|
|
private static List<ProtocolResolver<?>> 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;
|
}
|
|
/**
|
* 根据唯一排序号,查找对应的解析器对象。</p>
|
* 该方法在使用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;
|
}
|
|
/**
|
* 根据报文内容,找到使用的协议解析器。</p>
|
* 目前系统根据后缀来查找。</p>
|
* 该方法在老的对象中使用:<link>LongHandler</link>
|
* @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);
|
}
|
|
/**
|
* 返回系统定义的所有<code>ProtocolResolver</code>对象集合
|
* @return
|
*/
|
public static List<ProtocolResolver<?>> getProtocolResolverList(){
|
return cacheList;
|
}
|
|
private static class InnerComparator implements Comparator<ProtocolResolver<?>>{
|
@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());
|
}
|
}
|