// Path: src/wtf/socket/exception/fatal/WTFSocketProtocolBrokenException.java
// public class WTFSocketProtocolBrokenException extends WTFSocketFatalException {
// 
//     public WTFSocketProtocolBrokenException(String msg) {
//         super(msg);
//     }
// 
//     public int getErrCode() {
//         return 64;
//     }
// }
// 
// Path: src/wtf/socket/exception/fatal/WTFSocketProtocolUnsupportedException.java
// public class WTFSocketProtocolUnsupportedException extends WTFSocketFatalException {
// 
//     public WTFSocketProtocolUnsupportedException(String msg) {
//         super(msg);
//     }
// 
//     public int getErrCode() {
//         return 65;
//     }
// }
// 
// Path: src/wtf/socket/protocol/msg/WTFSocketDefaultProtocolParser.java
// public class WTFSocketDefaultProtocolParser implements WTFSocketProtocolParser {
// 
// 
//     @Override
//     public int getPriority() {
//         return WTFSocketPriority.LOWEST;
//     }
// 
//     @Override
//     public boolean isResponse(String data) {
//         return StringUtils.startsWith(data, "{") && StringUtils.endsWith(data, "}");
//     }
// 
//     @Override
//     public boolean isResponse(WTFSocketMsg msg) {
//         return StringUtils.equals(msg.getVersion(), "2.0");
//     }
// 
//     @Override
//     public WTFSocketMsg parse(String data) throws WTFSocketProtocolBrokenException {
//         try {
//             return JSON.parseObject(data, WTFSocketDefaultMsg.class);
//         } catch (Exception e) {
//             throw new WTFSocketProtocolBrokenException("Protocol broken [" + e.getMessage() + "]");
//         }
//     }
// 
//     @Override
//     public String parse(WTFSocketMsg msg) {
//         return JSON.toJSONString(msg);
//     }
// }


import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import wtf.socket.exception.fatal.WTFSocketProtocolBrokenException;
import wtf.socket.exception.fatal.WTFSocketProtocolUnsupportedException;
import wtf.socket.protocol.msg.WTFSocketDefaultProtocolParser;
import java.util.*;
package wtf.socket.protocol;



/**
 * 协议簇，通过向协议簇注册解析器
 * 将不同协议的数据包统一转化到 WTFSocketMsg
 * <p>
 * Created by ZFly on 2017/4/21.
 */
@Component
@Scope("prototype")
public class WTFSocketProtocolFamily {

    /**
     * 解析器列表
     */
    private Queue<WTFSocketProtocolParser> parsers = new PriorityQueue<WTFSocketProtocolParser>(Comparator.comparingInt(WTFSocketProtocolParser::getPriority)) {{
        add(new WTFSocketDefaultProtocolParser());
    }};

    /**
     * 选择解析器从字符串数据中解析出消息对象
     *
     * @param data 字符串数据
     *
     * @return 消息对象
     *
     * @throws WTFSocketProtocolBrokenException      消息格式错误
     * @throws WTFSocketProtocolUnsupportedException 没有适合的解析器
     */
    public WTFSocketMsg parse(String data) throws WTFSocketProtocolBrokenException, WTFSocketProtocolUnsupportedException {
        for (WTFSocketProtocolParser parser : parsers) {
            if (parser.isResponse(data)) {
                return parser.parse(data);
            }
        }
        throw new WTFSocketProtocolUnsupportedException("There was no protocol parser to convert string to message");
    }

    /**
     * 选择解析器将消息对象打包为字符串数据
     *
     * @param msg 消息对象
     *
     * @return 字符串数据
     */
    public String parse(WTFSocketMsg msg) throws WTFSocketProtocolUnsupportedException {
        for (WTFSocketProtocolParser parser : parsers) {
            if (parser.isResponse(msg)) {
                return parser.parse(msg);
            }
        }
// Path: src/wtf/socket/exception/fatal/WTFSocketProtocolBrokenException.java
// public class WTFSocketProtocolBrokenException extends WTFSocketFatalException {
// 
//     public WTFSocketProtocolBrokenException(String msg) {
//         super(msg);
//     }
// 
//     public int getErrCode() {
//         return 64;
//     }
// }
// 
// Path: src/wtf/socket/exception/fatal/WTFSocketProtocolUnsupportedException.java
// public class WTFSocketProtocolUnsupportedException extends WTFSocketFatalException {
// 
//     public WTFSocketProtocolUnsupportedException(String msg) {
//         super(msg);
//     }
// 
//     public int getErrCode() {
//         return 65;
//     }
// }
// 
// Path: src/wtf/socket/protocol/msg/WTFSocketDefaultProtocolParser.java
// public class WTFSocketDefaultProtocolParser implements WTFSocketProtocolParser {
// 
// 
//     @Override
//     public int getPriority() {
//         return WTFSocketPriority.LOWEST;
//     }
// 
//     @Override
//     public boolean isResponse(String data) {
//         return StringUtils.startsWith(data, "{") && StringUtils.endsWith(data, "}");
//     }
// 
//     @Override
//     public boolean isResponse(WTFSocketMsg msg) {
//         return StringUtils.equals(msg.getVersion(), "2.0");
//     }
// 
//     @Override
//     public WTFSocketMsg parse(String data) throws WTFSocketProtocolBrokenException {
//         try {
//             return JSON.parseObject(data, WTFSocketDefaultMsg.class);
//         } catch (Exception e) {
//             throw new WTFSocketProtocolBrokenException("Protocol broken [" + e.getMessage() + "]");
//         }
//     }
// 
//     @Override
//     public String parse(WTFSocketMsg msg) {
//         return JSON.toJSONString(msg);
//     }
// }


// Path: src/wtf/socket/protocol/WTFSocketProtocolFamily.java
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import wtf.socket.exception.fatal.WTFSocketProtocolBrokenException;
import wtf.socket.exception.fatal.WTFSocketProtocolUnsupportedException;
import wtf.socket.protocol.msg.WTFSocketDefaultProtocolParser;
import java.util.*;

package wtf.socket.protocol;



/**
 * 协议簇，通过向协议簇注册解析器
 * 将不同协议的数据包统一转化到 WTFSocketMsg
 * <p>
 * Created by ZFly on 2017/4/21.
 */
@Component
@Scope("prototype")
public class WTFSocketProtocolFamily {

    /**
     * 解析器列表
     */
    private Queue<WTFSocketProtocolParser> parsers = new PriorityQueue<WTFSocketProtocolParser>(Comparator.comparingInt(WTFSocketProtocolParser::getPriority)) {{
        add(new WTFSocketDefaultProtocolParser());
    }};

    /**
     * 选择解析器从字符串数据中解析出消息对象
     *
     * @param data 字符串数据
     *
     * @return 消息对象
     *
     * @throws WTFSocketProtocolBrokenException      消息格式错误
     * @throws WTFSocketProtocolUnsupportedException 没有适合的解析器
     */
    public WTFSocketMsg parse(String data) throws WTFSocketProtocolBrokenException, WTFSocketProtocolUnsupportedException {
        for (WTFSocketProtocolParser parser : parsers) {
            if (parser.isResponse(data)) {
                return parser.parse(data);
            }
        }
        throw new WTFSocketProtocolUnsupportedException("There was no protocol parser to convert string to message");
    }

    /**
     * 选择解析器将消息对象打包为字符串数据
     *
     * @param msg 消息对象
     *
     * @return 字符串数据
     */
    public String parse(WTFSocketMsg msg) throws WTFSocketProtocolUnsupportedException {
        for (WTFSocketProtocolParser parser : parsers) {
            if (parser.isResponse(msg)) {
                return parser.parse(msg);
            }
        }
        throw new WTFSocketProtocolUnsupportedException("There was no protocol parser to convert message to string");