shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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());
    }
}