001package gu.dtalk;
002
003import static com.google.common.base.Preconditions.checkArgument;
004import static gu.dtalk.CommonConstant.*;
005
006import com.alibaba.fastjson.JSONArray;
007import com.alibaba.fastjson.JSONObject;
008import com.google.common.base.MoreObjects;
009
010import net.gdface.utils.FaceUtilits;
011
012public class CommonUtils {
013
014        /**
015         * 返回响应通道名
016         * @param mac
017         * @return
018         */
019        public static String getAckChannel(String mac){
020                return mac + ACK_SUFFIX;
021        }
022        public static String getAckChannel(byte[] mac){
023                return getAckChannel(FaceUtilits.toHex(mac));
024        }
025        /**
026         * 生成连接频道名
027         * @param mac
028         * @return
029         */
030        public static String getConnChannel(String mac){
031                return mac + CONNECT_SUFFIX;
032        }
033        public static String getConnChannel(byte[] mac){
034                return getConnChannel(FaceUtilits.toHex(mac));
035        }
036        private static boolean hasField(Object resp,String name){
037                return resp instanceof JSONObject &&  ((JSONObject) resp).containsKey(name);
038        }
039        public static boolean isAck(Object resp){
040                return resp instanceof JSONObject &&  hasField((JSONObject) resp,ACK_FIELD_STATUS);
041        }
042        public static boolean isItem(Object resp){
043                return hasField(resp,ITEM_FIELD_NAME) 
044                                &&  hasField(resp,ITEM_FIELD_PATH) 
045                                && hasField(resp,ITEM_FIELD_CATALOG);
046        }       
047
048        public static CmdItem makeQuit(){
049                CmdItem item = new CmdItem();
050                item.setName(QUIT_NAME);
051                return item;
052        }
053        public static CmdItem makeBack(){
054                CmdItem item = new CmdItem();
055                item.setName(BACK_NAME);
056                return item;
057        }
058        public static boolean isBack(BaseItem item){
059                return (item instanceof BaseItem) && BACK_NAME.equals(item.getName());
060        }
061        public static boolean isRoot(JSONObject item){
062                return (item instanceof JSONObject) && "/".equals(item.getString(ITEM_FIELD_PATH));
063        }
064        public static boolean isRoot(BaseItem item){
065                return (item instanceof BaseItem) && null == item.getParent();
066        }
067        public static boolean isQuit(BaseItem item){
068                return (item instanceof BaseItem) && QUIT_NAME.equals(item.getName());
069        }
070        public static boolean isQuit(JSONObject item){
071                return (item instanceof JSONObject) && QUIT_NAME.equals(((JSONObject)item).getString(ITEM_FIELD_NAME));
072        }
073        public static boolean isQuit(JSONObject item, BaseItem start){
074                return isQuit(normalize(item,start));
075        }
076        public static boolean isQuit(Object item){
077                return isQuit((BaseItem) item)  || isQuit((JSONObject)item);
078        }
079        public static boolean isImage(JSONObject item){
080                return item == null ? false : OptionType.IMAGE.name().equals(item.getString(OPTION_FIELD_TYPE));
081        }
082        /**
083         * 归一化输入的{@link JSONObject}对象<br>
084         * 根据{@value CommonConstant#ITEM_FIELD_NAME}或{@value CommonConstant#ITEM_FIELD_PATH}字段的值
085         * 查找是否存在指定的item,如果不存在抛出异常,
086         * 如果没有定义{@value CommonConstant#ITEM_FIELD_NAME}或{@value CommonConstant#ITEM_FIELD_PATH}则抛出异常<br>
087         * 如果 {@link JSONObject}没有指定{@value CommonConstant#ITEM_FIELD_CATALOG}字段,
088         * 则设置为找到的item的对应字段.<br>
089         * 找到的item为{@link BaseOption}对象,且 {@link JSONObject}没有指定{@value CommonConstant#OPTION_FIELD_TYPE}字段,
090         * 则设置为找到的item的对应字段.
091         * @param jsonObject
092         * @param start 搜索起始对象
093         * @return 返回归一化的{@code jsonObject},
094         * 保证有定义{@value CommonConstant#ITEM_FIELD_NAME},{@value CommonConstant#ITEM_FIELD_PATH}字段
095         * @throws IllegalArgumentException
096         */
097        public static JSONObject normalize(JSONObject jsonObject, BaseItem start){
098                if(null != jsonObject && null != start){
099                        String name = jsonObject.getString(ITEM_FIELD_NAME);
100                        String path = jsonObject.getString(ITEM_FIELD_PATH);
101                        checkArgument(name != null || path != null,"NOT DEFINED path or name");
102                        BaseItem node;
103                        if(path != null){
104                                node = start.findChecked(path);
105                        }else if(name != null){
106                                node = start.findChecked(name);
107                        }else{
108                                throw new IllegalArgumentException("NOT DEFINED " + ITEM_FIELD_PATH +" or " + ITEM_FIELD_NAME);
109                        }
110                        if(jsonObject.containsKey(ITEM_FIELD_CATALOG)){
111                                checkArgument(node.getCatalog().equals(jsonObject.getObject(ITEM_FIELD_CATALOG, ItemType.class)),
112                                                "MISMATCH CATALOG %s",
113                                                node.getPath());
114                        }else{
115                                jsonObject.fluentPut(ITEM_FIELD_CATALOG, node.getCatalog());
116                        }
117                        if((node instanceof BaseOption)){
118                                BaseOption<?> opt = (BaseOption<?>)node;
119                                if(jsonObject.containsKey(OPTION_FIELD_TYPE)){
120                                        checkArgument(opt.getType().equals(jsonObject.getObject(OPTION_FIELD_TYPE,OptionType.class)),
121                                                        "MISMATCH TYPE %s",
122                                                        node.getPath());
123                                }else{
124                                        jsonObject.fluentPut(OPTION_FIELD_TYPE, opt.getType());
125                                }
126                        }
127                        if(name == null){
128                                jsonObject.fluentPut(ITEM_FIELD_NAME, node.getName());
129                        }
130                        for(Object child:MoreObjects.firstNonNull(jsonObject.getJSONArray(ITEM_FIELD_CHILDS),new JSONArray())){
131                                checkArgument(child instanceof JSONObject,"INVALID JSON FORMAT FOR CHILD OF %s",
132                                                node.getPath());
133                                normalize((JSONObject)child, node);
134                        }
135                }
136                return jsonObject;
137        }
138        
139}