├── .gitignore ├── README.md ├── imgs ├── index.png ├── index1.png ├── index2.png └── index3.png ├── pom.xml └── src ├── main └── java │ └── com │ └── zf │ └── zson │ ├── ZSON.java │ ├── ZsonUtils.java │ ├── common │ └── Utils.java │ ├── exception │ └── ZsonException.java │ ├── object │ └── ZsonObject.java │ ├── parse │ └── ZsonInfo.java │ ├── path │ ├── ZsonCurrentPath.java │ └── ZsonPath.java │ └── result │ ├── ZsonAction.java │ ├── ZsonActionAbstract.java │ ├── ZsonResult.java │ ├── ZsonResultAbstract.java │ ├── impl │ ├── ZsonAdd.java │ ├── ZsonDelete.java │ ├── ZsonResultImpl.java │ ├── ZsonRetrieve.java │ └── ZsonUpdate.java │ ├── info │ └── ZsonResultInfo.java │ └── utils │ ├── ZsonResultRestore.java │ └── ZsonResultToString.java └── test └── java └── com └── zf └── test └── Demo.java /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ 3 | /.classpath 4 | /.project 5 | /.settings/ 6 | /.idea/ 7 | /*.iml 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 前言 2 | ==== 3 | 4 | 现在大家都认可Python在接口测试方面效率比较高,究其原因,可能是Python的请求库功能强大,但Java的HttpClient封装得好的话,也可以一句代码发送请求,还有一点,Java的TestNg我个人认为是一个非常强大的测试框架,Python中的那些测试框架应该没有与之比肩的,但即便始此,Java在接口测试上还是举步维艰,这是因为在请求后对结果的处理,Python天然支持json解析,而Java呢?得依靠第三方库,且解析取值得一大片代码,更见鬼的是这一大片代码是毫无复用性可言,更有甚者,在解析时会搞一个pojo文件,更让Python者觉得用Java简直是灾难。 5 | 6 | 为了解决测试人员在Java对json解析的困惑,zson就应运而生了。因为我本人做过UI自动化测试,对XPATH有一定的了解,所以zson对json的操作中加入了一个类似于xpath的路径的概念,即利用一个路径来操作json串。如果一个json串有非常复杂的层级关系,如果想获取最里面的某个key的值,正常情况下那就得一层一层的解析进去,非常的繁琐,如果用zson,只需要一句代码,给定一个路径(值得注意的是,也可以是相对路径哦),就可以获取到对应的值,这样可以大大的提高生产力。 7 | 8 | 作者联系方式 9 | ==== 10 | 11 | QQ:408129370 12 | 13 | QQ群:536192476 14 | 15 | MAVEN仓库地址 16 | ==== 17 | 18 | https://mvnrepository.com/artifact/link.zhangfei/zson 19 | 20 | 使用场景 21 | ==== 22 | 设定一个json串: 23 | ``` 24 | { 25 | "retCode": "200", 26 | "retMsg": "success", 27 | "data": [ 28 | { 29 | "id": 1, 30 | "name": "test", 31 | "date": "2017-01-09 13:30:00" 32 | }, 33 | { 34 | "id": 2, 35 | "name": "test1", 36 | "date": "2017-01-09 13:40:00" 37 | } 38 | ] 39 | } 40 | ``` 41 | 如果想要获取以上json串的所有"name"的值,对于正常解析,你得遍历,但对于zson,你只需要这样: 42 | ``` 43 | ZsonResult zr = ZSON.parseJson(json); 44 | List names = zr.getValues("//name"); 45 | ``` 46 | 我们在进行结果断言时,有时候请求返回的一整个json串作为一个期望值来进行断言,但json串中往往会存在有不固定的值,比如上面json串的"date",每次都是变化的,这样就不好断言了,于是,在zson中,我们可以把这个date的值进行更改,改成一个固定的值: 47 | ``` 48 | ZsonResult zr = ZSON.parseJson(json); 49 | zr.updateValue("//date","0000-00-00 00:00:00"); 50 | ``` 51 | 或者干脆删除这个结点: 52 | ``` 53 | ZsonResult zr = ZSON.parseJson(json); 54 | zr.deleteValue("//date"); 55 | ``` 56 | 以上zson对json串的操作包含了查找,更新,删除。zson还有对json串中增加一个子字符串的操作: 57 | ``` 58 | ZsonResult zr = ZSON.parseJson(json); 59 | zr.addValue("/data/*[2]","{\"id\":3,\"name\":\"test2\",\"date\":\"2017-01-09 14:30:00\"}"); 60 | ``` 61 | 62 | 选择器path说明 63 | ==== 64 | 65 | 示例一: 66 | 67 | ``` 68 | [ 69 | { 70 | "firstName": "Eric", 71 | "lastName": "Clapton", 72 | "instrument": "guitar" 73 | }, 74 | { 75 | "firstName": "Sergei", 76 | "lastName": "Rachmaninoff", 77 | "instrument": "piano" 78 | } 79 | ] 80 | ``` 81 | 82 | > 找出第二个firstName: /*[1]/firstName 83 | > 输出:Sergei 84 | *** 85 | > 找出第一个Map: /*[0] 86 | > 输出:{"firstName": "Eric","lastName": "Clapton","instrument": "guitar"} 87 | *** 88 | > 找出所有的firstName: //firstName 89 | > 输出:["Eric","Sergei"] 90 | *** 91 | 92 | 示例二: 93 | 94 | `{"a":["a"],"cb":{"a":1},"d":["a",{"a":[1,2]},{"a":2},""],"e":"b"}` 95 | 96 | > 路径: /d/*[1]/a 97 | > 输出:[1,2] 98 | *** 99 | > 路径: /d/*[1]/a/*[0] 100 | > 输出:1 101 | *** 102 | 103 | zson 104 | ==== 105 | 106 | #### 专为测试人员打造的JSON解析器 107 | 108 | 当然,有很多很好的JSON解析的JAR包,比如JSONOBJECT,GSON,甚至也有为我们测试人员而打造的JSONPATH,但我还是自已实现了一下(之前也实现过,现在属于重构)。其主要特点是用一个类似于xpath的选择器来获取相应的值。 109 | 110 | *** 111 | 112 | #### 特点 113 | 114 | + 无需层层解析 115 | + 根据给定的路径(类XPATH路径)来获取相应的值 116 | + 支持相对路径 117 | 118 | *** 119 | 120 | #### 实现思路 121 | 122 | 思想是这样的,以这个JSON串为例(我自已随手写的): 123 | 124 | ``` 125 | {"a":"b","cb":{"a":1},"d":["a",{"a":3},{"a":2},""],"e":"b"} 126 | ``` 127 | 128 | ``` 129 | { 130 | "a": "b", 131 | "cb": { 132 | "a": 1 133 | }, 134 | "d": [ 135 | "a", 136 | { 137 | "a": 3 138 | }, 139 | { 140 | "a": 2 141 | }, 142 | "" 143 | ], 144 | "e": "b" 145 | } 146 | ``` 147 | 148 | 我们在保证只扫描一次字符串的情况下,就把JSON串解析成功。于是,我先定义了一个List: 149 | 150 | `private List collections = new ArrayList();` 151 | 152 | collections用来存放这个JSON串中所有的LIST与MAP,在扫描时,一旦碰到{或[,就new一个Map或List,然后add到collections中去了: 153 | 154 | ![image](https://github.com/zhangfei19841004/zson/blob/master/imgs/index.png) 155 | 156 | 存放进去后,我们需要一个map来记录collections里的list或map的状态,比如是否已经闭合了,是一个list还是一个map,在collections中的index: 157 | 158 | `private Map> index = new HashMap>();` 159 | 160 | ![image](https://github.com/zhangfei19841004/zson/blob/master/imgs/index1.png) 161 | 162 | 可以看到,这个MAP的key是由1 1.1 1.2 1.1.1这样来组成的,所以,这个key就可以用来表示json的层级结构了,当然我还用了一个list来保存这些key的顺序: 163 | 164 | `private List level = new ArrayList();` 165 | 166 | ![image](https://github.com/zhangfei19841004/zson/blob/master/imgs/index2.png) 167 | 168 | 这样一来,数据结构就很清晰了。接下来要做的事,就是在扫描中的一些判断了,保持以下几个点: 169 | 170 | 1. 碰到[或{就new一个对象,并将对象存放到collections中去 171 | 172 | 2. 碰到'\\'需要转义的,得直接跳过去,并存放到扫描出来的临时变量中去。比如\\{就不需要new一个对象 173 | 174 | 3. 碰到"符号,就要打个标记,在下一个"出现之前,把扫描出来的都当成一个字符串放到临时变量中去。 175 | 176 | 4. 碰到:符号,就要开始标记是个map的开始了,并把之后出现的字符串都存放到另一个临时变量中去。 177 | 178 | 5. 碰到,符号,就要开始处理临时变量了,如果是map就把之前存的两个昨时变量,一个作为KEY,一个作为VALUE,都放到collections中对应的map中去,如果是list,则把之前存的第一个临时变量,放到collections对应的list中去。 179 | 180 | 6. 碰到]或}符号,则表示一个list或map被解析完全了,则这时候要去更新index中的对应的list或map的状态了。 181 | 182 | 解析完了后,所有的数据都在collections index level这三个变量中了,于是,我们只需要定一个取数据的规则就行了,我用的是一种类似于xpath的语法格式来取值的,这时候只需要解析下这个xpath路径就可以得出这个key,然后在collections中拿值就可以了! 183 | 184 | *** 185 | 186 | #### 使用方法 187 | 188 | ![image](https://github.com/zhangfei19841004/zson/blob/master/imgs/index3.png) 189 | 190 | >备注:上面的例子中,我们可以看到,类XPATH的路径支持绝对路径和相对路径,用\*\[]来表示一个list,[]里面放要获取的值在list中的index,比如/*\[0]指获取list中的第1个值。用map的key来获取其对应的值! 191 | 192 | *** 193 | 194 | #### 使用说明(老版本,现在可忽略!) 195 | 196 | ``` 197 | Zson z = new Zson(); //new一个Zson对象 198 | 199 | ZsonResult zr = z.parseJson(j); //解析JSON字符串后,得到一个ZsonResult对象 200 | ``` 201 | 202 | > zr对象可用的方法: 203 | 204 | ``` 205 | Object getValue(String path) //返回一个除了List或Map的Object对象,如果是List或Map,会转换成为JSON字符串返回 206 | 207 | Map getMap(String path) //返回一个Map对象 208 | 209 | List getList(String path) //返回一个List对象 210 | 211 | String toJsonString(Object obj) //将Map或List转换成为JSON字符串 212 | ``` 213 | *** 214 | 215 | #### 2016年4月16日更新日志 216 | 217 | ``` 218 | 支持相对路径! 219 | 示例二中: 220 | getValues() 221 | zr.getValues("/a//*[0]"));//输出[a] 222 | zr.getValues("//*[1]"));//输出[2] 223 | 说明:相对路径所得出来的值只显示非MAP或LIST的值,如果是MAP或LIST,则会被忽略! 224 | ``` 225 | 226 | #### 2016年6月16日更新日志 227 | 228 | ``` 229 | 更加丰富的API: 230 | String s1 = "[{ \"firstName\": \"Eric\", \"lastName\": \"Clapton\", \"instrument\": \"guitar\" },{ \"firstName\": \"Sergei\", \"lastName\": \"Rachmaninoff\", \"instrument\": \"piano\" }] "; 231 | String s2 = "[0,1,2,3.14,4.00,\"3\",true,\"\"]"; 232 | String s3 = "{\"a\":[\"a1\"],\"cb\":{\"a\":1},\"d\":[\"a\",{\"a\":[1,20]},{\"a\":2},\"\"],\"e\":\"b\"}"; 233 | Zson z = new Zson(); 234 | ZsonResult zr1 = z.parseJson(s1); 235 | System.out.println(zr1.getValue("/*[1]/firstName")); 236 | System.out.println(zr1.getMap("/*[1]")); 237 | 238 | ZsonResult zr2 = z.parseJson(s2); 239 | System.out.println(zr2.getInteger("/*[1]")); 240 | System.out.println(zr2.getLong("/*[2]")); 241 | System.out.println(zr2.getDouble("/*[3]")); 242 | System.out.println(zr2.getFloat("/*[4]")); 243 | System.out.println(zr2.getString("/*[5]")); 244 | System.out.println(zr2.getBoolean("/*[6]")); 245 | 246 | ZsonResult zr3 = z.parseJson(s3); 247 | System.out.println(zr3.getValues("//*[0]")); 248 | System.out.println(zr3.getValues("//*[1]")); 249 | System.out.println(zr3.getList("/a")); 250 | System.out.println(zr3.getMap("/cb")); 251 | ``` 252 | 253 | #### 2016年6月28日更新日志 254 | ``` 255 | 增加API: 256 | removeValue(String path); 257 | 功能:移除JSON串中的某个map,list或值,path为绝对路径 258 | 259 | getResult(); 260 | 功能:返回解析完的整个数据对象 261 | ``` 262 | 263 | #### 2017年1月3日更新日志(新版本!) 264 | 265 | 这次更新主要是对结果的处理进行了重构,因为考虑到结果的处理主要是用到了路径,所以在解析json串时,将每个结点的路径给保存下来了,相当于给结果做了一个索引,这样处理结果时,就非常的快,且非常的方便了。重构后的API解释如下: 266 | 267 | ``` 268 | public boolean isValid();//判断json串是否合法 269 | 270 | public Object getResult();//获取整个结果对象 271 | 272 | public Object getValue(String path);//根据路径获取结果集的第一个值 273 | 274 | public Object getValue();//获取整个结果json字符串 275 | 276 | public List getValues(String path);//获取符合路径的所有结果集 277 | 278 | public String getString(String path);//根据路径获取结果集的第一个值,并转换为字符串 279 | 280 | public int getInteger(String path);//根据路径获取结果集的第一个值,并转换为Integer 281 | 282 | public long getLong(String path);//根据路径获取结果集的第一个值,并转换为Long 283 | 284 | public double getDouble(String path);//根据路径获取结果集的第一个值,并转换为Double 285 | 286 | public float getFloat(String path);//根据路径获取结果集的第一个值,并转换为Float 287 | 288 | public boolean getBoolean(String path);//根据路径获取结果集的第一个值,并转换为Boolean 289 | 290 | public void addValue(String path, Object json);//在路径path下添加一个key为'key',value为'json' 291 | 292 | public void deleteValue(String path);//删除path的所有对象 293 | 294 | public void updateValue(String path, Object json);//更新path的值为'json' 295 | ``` 296 | -------------------------------------------------------------------------------- /imgs/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangfei19841004/zson/b44d50896eb59bafea110cc80894a7f9d0a468ad/imgs/index.png -------------------------------------------------------------------------------- /imgs/index1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangfei19841004/zson/b44d50896eb59bafea110cc80894a7f9d0a468ad/imgs/index1.png -------------------------------------------------------------------------------- /imgs/index2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangfei19841004/zson/b44d50896eb59bafea110cc80894a7f9d0a468ad/imgs/index2.png -------------------------------------------------------------------------------- /imgs/index3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangfei19841004/zson/b44d50896eb59bafea110cc80894a7f9d0a468ad/imgs/index3.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | org.sonatype.oss 6 | oss-parent 7 | 7 8 | 9 | 10 | 11 | 12 | The Apache Software License, Version 2.0 13 | http://www.apache.org/licenses/LICENSE-2.0.txt 14 | repo 15 | 16 | 17 | 18 | 19 | scm:git:git@github.com:zhangfei19841004/zson.git 20 | scm:git:git@github.com:zhangfei19841004/zson.git 21 | https://github.com/zhangfei19841004/zson 22 | master 23 | 24 | 25 | 26 | 27 | zhangfei 28 | zhangfei19841004@163.com 29 | zhangfei 30 | https://github.com/zhangfei19841004 31 | 32 | 33 | 34 | 4.0.0 35 | link.zhangfei 36 | zson 37 | ZSON 38 | 1.1 39 | 专为测试人员打造的json解析器 40 | 41 | 42 | 1.6 43 | 44 | 45 | 46 | ${project.artifactId} 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-compiler-plugin 51 | 2.1 52 | 53 | ${java-version} 54 | ${java-version} 55 | UTF-8 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-jar-plugin 61 | 2.4 62 | 63 | 64 | 65 | true 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-source-plugin 73 | 2.2.1 74 | 75 | 76 | attach-sources 77 | 78 | jar-no-fork 79 | 80 | 81 | 82 | 83 | 84 | org.apache.maven.plugins 85 | maven-javadoc-plugin 86 | 2.9.1 87 | 88 | 89 | attach-javadocs 90 | 91 | jar 92 | 93 | 94 | 95 | 96 | 110 | 111 | 112 | 113 | 114 | 115 | oss 116 | https://oss.sonatype.org/content/repositories/snapshots/ 117 | 118 | 119 | 120 | oss 121 | Maven Central Staging Repository 122 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/ZSON.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson; 2 | 3 | import com.zf.zson.common.Utils; 4 | import com.zf.zson.exception.ZsonException; 5 | import com.zf.zson.object.ZsonObject; 6 | import com.zf.zson.parse.ZsonInfo; 7 | import com.zf.zson.result.ZsonResult; 8 | import com.zf.zson.result.impl.ZsonResultImpl; 9 | import com.zf.zson.result.info.ZsonResultInfo; 10 | import com.zf.zson.result.utils.ZsonResultToString; 11 | 12 | import java.math.BigDecimal; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | public class ZSON { 18 | 19 | public static ZsonResult parseJson(String json) { 20 | ZsonParse zp = new ZsonParse(json); 21 | return zp.fromJson(true); 22 | } 23 | 24 | public static ZsonResult parseJson(String json, boolean linked) { 25 | ZsonParse zp = new ZsonParse(json); 26 | return zp.fromJson(linked); 27 | } 28 | 29 | public static String toJsonString(Object object) { 30 | ZsonResultToString zrt = new ZsonResultToString(); 31 | return zrt.toJsonString(object); 32 | } 33 | 34 | public static class ZsonParse { 35 | 36 | private ZsonResultInfo zResultInfo; 37 | 38 | private String json; 39 | 40 | private ZsonParse(String json) { 41 | this.json = json; 42 | } 43 | 44 | private void addElementToCollections(int type, String element, String v, boolean isFinished) { 45 | try { 46 | int lastUNFIndex = this.getLatestUNFinishedLevelIndex(); 47 | Map elementStatus = zResultInfo.getIndex().get(zResultInfo.getLevel().get(lastUNFIndex)); 48 | Object classType = Object.class; 49 | if (elementStatus.get(ZsonUtils.TYPE) != type) { 50 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 51 | } else { 52 | Object elementObj = zResultInfo.getCollections().get(elementStatus.get(ZsonUtils.INDEX)); 53 | ZsonObject eObj = new ZsonObject(); 54 | eObj.objectConvert(elementObj); 55 | if (type == 1) { 56 | List elementList = eObj.getZsonList(); 57 | if (!(elementList.size() == 0 && element.equals("") && isFinished)) { 58 | Object temp = this.getElementInstance(element); 59 | elementList.add(temp); 60 | if (temp != null) { 61 | classType = temp.getClass(); 62 | } 63 | } 64 | } else { 65 | Map elementMap = eObj.getZsonMap(); 66 | if (!(elementMap.size() == 0 && element.equals("") && v.equals("") && isFinished)) { 67 | Object temp = this.getElementInstance(v); 68 | elementMap.put(this.getElementInstance(element).toString(), temp); 69 | if (temp != null) { 70 | classType = temp.getClass(); 71 | } 72 | } 73 | } 74 | } 75 | this.setElementPath(type, lastUNFIndex, element); 76 | this.setElementClassType(type, lastUNFIndex, element, classType); 77 | if (isFinished) { 78 | elementStatus.put(ZsonUtils.STATUS, 1); 79 | } 80 | } catch (Exception e) { 81 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 82 | } 83 | } 84 | 85 | private void setElementPath(int type, int index, String element) { 86 | ZsonObject pathObj = new ZsonObject(); 87 | pathObj.objectConvert(zResultInfo.getPath().get(index)); 88 | String parentPath = this.getParentPath(zResultInfo.getLevel().get(index)); 89 | if (type == 1) { 90 | List pathObjList = pathObj.getZsonList(); 91 | String path = parentPath + "/*[" + pathObjList.size() + "]"; 92 | pathObjList.add(path); 93 | } else { 94 | Map pathObjMap = pathObj.getZsonMap(); 95 | String pathKey = this.getElementInstance(element).toString(); 96 | String path = parentPath + "/" + pathKey; 97 | pathObjMap.put(pathKey, path); 98 | } 99 | } 100 | 101 | private void setElementClassType(int type, int index, String element, Object classType) { 102 | ZsonObject classTypeObj = new ZsonObject(); 103 | classTypeObj.objectConvert(zResultInfo.getClassTypes().get(index)); 104 | if (type == 1) { 105 | List classTypeObjList = classTypeObj.getZsonList(); 106 | classTypeObjList.add(classType); 107 | } else { 108 | Map classTypeObjMap = classTypeObj.getZsonMap(); 109 | classTypeObjMap.put(this.getElementInstance(element).toString(), classType); 110 | } 111 | } 112 | 113 | private String getParentPath(String key) { 114 | if (ZsonUtils.BEGIN_KEY.equals(key)) { 115 | return ""; 116 | } 117 | String pKey = key.substring(0, key.lastIndexOf('.')); 118 | Map pIndexInfo = this.getIndexInfoByKey(pKey); 119 | int pType = pIndexInfo.get(ZsonUtils.TYPE); 120 | int pIndex = pIndexInfo.get(ZsonUtils.INDEX); 121 | ZsonObject pPathObj = new ZsonObject(); 122 | pPathObj.objectConvert(zResultInfo.getPath().get(pIndex)); 123 | ZsonObject collectionObj = new ZsonObject(); 124 | collectionObj.objectConvert(zResultInfo.getCollections().get(pIndexInfo.get(ZsonUtils.INDEX))); 125 | if (pType == 0) { 126 | Map pElement = collectionObj.getZsonMap(); 127 | for (String k : pElement.keySet()) { 128 | ZsonObject pObj = new ZsonObject(); 129 | pObj.objectConvert(pElement.get(k)); 130 | if (pObj.isMap()) { 131 | if (key.equals(pObj.getZsonMap().get(ZsonUtils.LINK))) { 132 | return pPathObj.getZsonMap().get(k); 133 | } 134 | } else if (pObj.isList()) { 135 | if (key.equals(pObj.getZsonList().get(0))) { 136 | return pPathObj.getZsonMap().get(k); 137 | } 138 | } 139 | } 140 | } else { 141 | List pElement = collectionObj.getZsonList(); 142 | for (int i = 0; i < pElement.size(); i++) { 143 | ZsonObject pObj = new ZsonObject(); 144 | pObj.objectConvert(pElement.get(i)); 145 | if (pObj.isMap()) { 146 | if (key.equals(pObj.getZsonMap().get(ZsonUtils.LINK))) { 147 | return pPathObj.getZsonList().get(i); 148 | } 149 | } else if (pObj.isList()) { 150 | if (key.equals(pObj.getZsonList().get(0))) { 151 | return pPathObj.getZsonList().get(i); 152 | } 153 | } 154 | } 155 | } 156 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 157 | } 158 | 159 | private void setLatestUNFinishedToFinished() { 160 | try { 161 | int lastUNFIndex = this.getLatestUNFinishedLevelIndex(); 162 | Map elementStatus = zResultInfo.getIndex().get(zResultInfo.getLevel().get(lastUNFIndex)); 163 | elementStatus.put(ZsonUtils.STATUS, 1); 164 | } catch (Exception e) { 165 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 166 | } 167 | } 168 | 169 | private Map getIndexInfoByKey(String key) { 170 | if (zResultInfo.getIndex().containsKey(key)) { 171 | return zResultInfo.getIndex().get(key); 172 | } else { 173 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 174 | } 175 | } 176 | 177 | private void addToParent(ZsonInfo zinfo, String key) { 178 | try { 179 | String pKey = key.substring(0, key.lastIndexOf('.')); 180 | Map pElement = this.getIndexInfoByKey(pKey); 181 | if (zinfo.isMap() && pElement.get(ZsonUtils.TYPE) == 1) { 182 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 183 | } 184 | ZsonObject elementObj = new ZsonObject(); 185 | elementObj.objectConvert(zResultInfo.getCollections().get(pElement.get(ZsonUtils.INDEX))); 186 | if (zinfo.isMap()) { 187 | Map elementMap = elementObj.getZsonMap(); 188 | Map temp = Utils.getMap(zResultInfo.isLinked()); 189 | temp.put(ZsonUtils.LINK, key); 190 | elementMap.put(this.getElementInstance(zinfo.getElement()).toString(), temp); 191 | } else { 192 | List elementList = elementObj.getZsonList(); 193 | List temp = new ArrayList(); 194 | temp.add(key); 195 | elementList.add(temp); 196 | } 197 | this.setElementPath(pElement.get(ZsonUtils.TYPE), pElement.get(ZsonUtils.INDEX), zinfo.getElement()); 198 | Map cElement = this.getIndexInfoByKey(key); 199 | this.setElementClassType(pElement.get(ZsonUtils.TYPE), pElement.get(ZsonUtils.INDEX), zinfo.getElement(), cElement.get(ZsonUtils.TYPE) == 0 ? Map.class : List.class); 200 | } catch (Exception e) { 201 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 202 | } 203 | } 204 | 205 | private String addZsonResultInfo(int type) { 206 | Object pathObj = null; 207 | Object classTypeObj = null; 208 | if (type == 0) { 209 | zResultInfo.getCollections().add(Utils.getMap(zResultInfo.isLinked())); 210 | pathObj = Utils.getMap(zResultInfo.isLinked()); 211 | classTypeObj = Utils.getMap(zResultInfo.isLinked()); 212 | } else if (type == 1) { 213 | zResultInfo.getCollections().add(new ArrayList()); 214 | pathObj = new ArrayList(); 215 | classTypeObj = new ArrayList(); 216 | } 217 | int status = 0; 218 | int index = 0; 219 | String key = ZsonUtils.BEGIN_KEY; 220 | if (zResultInfo.getLevel().size() != 0) { 221 | index = zResultInfo.getCollections().size() - 1; 222 | int latestIndex = this.getLatestFinishedLevelIndex(); 223 | key = this.generateIndexKey(zResultInfo.getLevel().get(latestIndex)); 224 | } 225 | zResultInfo.getLevel().add(key); 226 | zResultInfo.getPath().add(pathObj); 227 | zResultInfo.getClassTypes().add(classTypeObj); 228 | Map objMap = Utils.getMap(zResultInfo.isLinked()); 229 | objMap.put(ZsonUtils.TYPE, type); 230 | objMap.put(ZsonUtils.STATUS, status); 231 | objMap.put(ZsonUtils.INDEX, index); 232 | zResultInfo.getIndex().put(key, objMap); 233 | return key; 234 | } 235 | 236 | /** 237 | * 获取最新的没有解析完成的index,从level中获取 238 | * 239 | * @return 240 | */ 241 | private int getLatestFinishedLevelIndex() { 242 | for (int i = zResultInfo.getLevel().size() - 1; i >= 0; i--) { 243 | if (zResultInfo.getIndex().get(zResultInfo.getLevel().get(i)).get(ZsonUtils.STATUS) == 0) { 244 | return i; 245 | } 246 | } 247 | return -1; 248 | } 249 | 250 | private int getLatestUNFinishedLevelIndex() { 251 | for (int i = zResultInfo.getLevel().size() - 1; i >= 0; i--) { 252 | if (zResultInfo.getIndex().get(zResultInfo.getLevel().get(i)).get(ZsonUtils.STATUS) == 0) { 253 | return i; 254 | } 255 | } 256 | return -1; 257 | } 258 | 259 | private String generateIndexKey(String parentKey) { 260 | int begin = 1; 261 | while (true) { 262 | if (zResultInfo.getIndex().containsKey(parentKey + "." + begin)) { 263 | begin++; 264 | } else { 265 | return parentKey + "." + begin; 266 | } 267 | } 268 | } 269 | 270 | private boolean isValidMapKey(String element) { 271 | char[] c = element.toCharArray(); 272 | return c[0] == ZsonUtils.jsonStringBegin && c[c.length - 1] == ZsonUtils.jsonStringEnd; 273 | } 274 | 275 | private Object getElementInstance(String element) { 276 | try { 277 | if (element.startsWith("\"") && element.endsWith("\"")) { 278 | return element.substring(1, element.length() - 1); 279 | } else if (element.equals("true")) { 280 | return true; 281 | } else if (element.equals("false")) { 282 | return false; 283 | } else if (element.equals("null")) { 284 | return null; 285 | } else { 286 | return this.getBigDecimalValue(element); 287 | } 288 | } catch (Exception e) { 289 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 290 | } 291 | } 292 | 293 | private void handleListBegin(ZsonInfo zinfo) { 294 | String key = this.addZsonResultInfo(1); 295 | if (!ZsonUtils.BEGIN_KEY.equals(key)) { 296 | this.addToParent(zinfo, key); 297 | zinfo.setElement(null); 298 | zinfo.setMap(false); 299 | zinfo.setElementSeparate(false); 300 | } 301 | } 302 | 303 | private void handleMapBegin(ZsonInfo zinfo) { 304 | String key = this.addZsonResultInfo(0); 305 | if (!ZsonUtils.BEGIN_KEY.equals(key)) { 306 | this.addToParent(zinfo, key); 307 | zinfo.setElement(null); 308 | zinfo.setMap(false); 309 | zinfo.setElementSeparate(false); 310 | } 311 | } 312 | 313 | private void handleFormatString(StringBuffer sb, char[] chars, int i) { 314 | try { 315 | sb.append(chars[i]); 316 | sb.append(chars[i + 1]); 317 | } catch (Exception e) { 318 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 319 | } 320 | } 321 | 322 | private void handleStringBegin(ZsonInfo zinfo, StringBuffer sb, char temp) { 323 | zinfo.setMarkIndex(zinfo.getMarkIndex() + 1); 324 | sb.append(temp); 325 | if (!zinfo.isMark()) { 326 | zinfo.setMark(true); 327 | } else { 328 | zinfo.setMark(false); 329 | } 330 | zinfo.setElementSeparate(false); 331 | } 332 | 333 | private void handleMapConnector(ZsonInfo zinfo, StringBuffer sb) { 334 | if (zinfo.isMark() || zinfo.getMarkIndex() % 2 != 0 || sb.length() == 0 || zinfo.isMap() || zinfo.isElementSeparate()) { 335 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 336 | } 337 | zinfo.setMap(true); 338 | zinfo.setElement(sb.toString().trim()); 339 | sb.delete(0, sb.length()); 340 | } 341 | 342 | private void handleElementConnector(ZsonInfo zinfo, StringBuffer sb) { 343 | if (zinfo.isMap()) { 344 | zinfo.setV(sb.toString().trim()); 345 | } else { 346 | zinfo.setElement(sb.toString().trim()); 347 | } 348 | if (zinfo.isElementSeparate() || zinfo.isMark() || zinfo.getMarkIndex() % 2 != 0 || (zinfo.isMap() && (!zinfo.getElement().equals("") && !this.isValidMapKey(zinfo.getElement())))) { 349 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 350 | } 351 | if (!zinfo.getElement().equals("")) { 352 | if (zinfo.isMap()) { 353 | this.addElementToCollections(0, zinfo.getElement(), zinfo.getV(), false); 354 | zinfo.setMap(false); 355 | } else { 356 | this.addElementToCollections(1, zinfo.getElement(), null, false); 357 | } 358 | } 359 | zinfo.setElement(null); 360 | zinfo.setV(null); 361 | zinfo.setElementSeparate(true); 362 | sb.delete(0, sb.length()); 363 | } 364 | 365 | private void handleElementEnd(ZsonInfo zinfo, StringBuffer sb) { 366 | if (zinfo.isMap()) { 367 | zinfo.setV(sb.toString().trim()); 368 | } else { 369 | zinfo.setElement(sb.toString().trim()); 370 | } 371 | if (zinfo.isElementSeparate() || zinfo.isMark() || zinfo.getMarkIndex() % 2 != 0 || (zinfo.isMap() && (!zinfo.getElement().equals("") && !this.isValidMapKey(zinfo.getElement())))) { 372 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 373 | } 374 | if (!zinfo.getElement().equals("")) { 375 | if (zinfo.isMap()) { 376 | this.addElementToCollections(0, zinfo.getElement(), zinfo.getV(), true); 377 | zinfo.setMap(false); 378 | } else { 379 | this.addElementToCollections(1, zinfo.getElement(), null, true); 380 | } 381 | } else { 382 | this.setLatestUNFinishedToFinished(); 383 | } 384 | zinfo.setElement(null); 385 | zinfo.setV(null); 386 | sb.delete(0, sb.length()); 387 | } 388 | 389 | public ZsonResult fromJson(boolean linked) { 390 | if (json == null || json.trim().equals("")) { 391 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 392 | } 393 | char[] chars = json.toCharArray(); 394 | if (chars[0] != ZsonUtils.jsonListBegin && chars[0] != ZsonUtils.jsonMapBegin) { 395 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 396 | } 397 | ZsonInfo zinfo = new ZsonInfo(); 398 | ZsonResultImpl zResult = new ZsonResultImpl(linked); 399 | zResultInfo = zResult.getzResultInfo(); 400 | StringBuffer sb = new StringBuffer(); 401 | for (int i = 0; i < chars.length; i++) { 402 | char temp = chars[i]; 403 | if (!zinfo.isMark() && temp == ZsonUtils.jsonListBegin) { 404 | this.handleListBegin(zinfo); 405 | continue; 406 | } else if (!zinfo.isMark() && temp == ZsonUtils.jsonMapBegin) { 407 | this.handleMapBegin(zinfo); 408 | continue; 409 | } else if (temp == '\\') { 410 | this.handleFormatString(sb, chars, i); 411 | i++; 412 | continue; 413 | } else if (temp == ZsonUtils.jsonStringBegin) { 414 | this.handleStringBegin(zinfo, sb, temp); 415 | continue; 416 | } else if (!zinfo.isMark() && temp == ZsonUtils.jsonMapConnector) { 417 | this.handleMapConnector(zinfo, sb); 418 | continue; 419 | } else if (!zinfo.isMark() && temp == ZsonUtils.jsonElementConnector) { 420 | this.handleElementConnector(zinfo, sb); 421 | } else if (!zinfo.isMark() && (temp == ZsonUtils.jsonListEnd || temp == ZsonUtils.jsonMapEnd)) { 422 | this.handleElementEnd(zinfo, sb); 423 | } else { 424 | zinfo.setElementSeparate(false); 425 | sb.append(temp); 426 | } 427 | } 428 | if (!zResult.isValid()) { 429 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 430 | } 431 | return zResult; 432 | } 433 | 434 | private BigDecimal getBigDecimalValue(String math) { 435 | BigDecimal bd = new BigDecimal(math); 436 | return bd; 437 | } 438 | 439 | } 440 | } 441 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/ZsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson; 2 | 3 | /** 4 | * @author zhangfei 5 | * @net id: 再见理想 6 | * @QQ: 408129370 7 | * @博客地址: http://www.cnblogs.com/zhangfei/ 8 | */ 9 | public class ZsonUtils { 10 | 11 | public final static char jsonStringBegin = '"'; 12 | public final static char jsonStringEnd = '"'; 13 | public final static char jsonElementConnector = ','; 14 | 15 | public final static char jsonListBegin = '['; 16 | public final static char jsonListEnd = ']'; 17 | 18 | public final static char jsonMapBegin = '{'; 19 | public final static char jsonMapEnd = '}'; 20 | public final static char jsonMapConnector = ':'; 21 | 22 | public final static String LINK = "link"; 23 | 24 | public final static String TYPE = "type"; 25 | public final static String STATUS = "status"; 26 | public final static String INDEX = "index"; 27 | 28 | public final static String BEGIN_KEY = "1"; 29 | 30 | public final static String JSON_NOT_VALID = "这不是一个合法的JSON串!"; 31 | 32 | public static String convert(String utfString) { 33 | StringBuilder sb = new StringBuilder(); 34 | int i = -1; 35 | int pos = 0; 36 | while ((i = utfString.indexOf("\\u", pos)) != -1) { 37 | sb.append(utfString.substring(pos, i)); 38 | if (i + 5 < utfString.length()) { 39 | pos = i + 6; 40 | sb.append((char) Integer.parseInt(utfString.substring(i + 2, i + 6), 16)); 41 | } 42 | } 43 | sb.append(utfString.substring(pos)); 44 | return sb.toString(); 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/common/Utils.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.common; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by zhangfei on 2018/1/31/031. 9 | */ 10 | public class Utils { 11 | 12 | public static Map getMap(boolean linked) { 13 | if (linked) { 14 | return new LinkedHashMap(); 15 | } 16 | return new HashMap(); 17 | } 18 | 19 | public static void main(String[] args) { 20 | Map m = Utils.getMap(true); 21 | m.put("a", "b"); 22 | System.out.println(m); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/exception/ZsonException.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.exception; 2 | 3 | /** 4 | * Created by zhangfei on 2018/1/31/031. 5 | */ 6 | public class ZsonException extends RuntimeException { 7 | 8 | public ZsonException() { 9 | } 10 | 11 | public ZsonException(String message) { 12 | super(message); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/object/ZsonObject.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.object; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class ZsonObject { 7 | 8 | private Map zsonMap; 9 | 10 | private List zsonList; 11 | 12 | private boolean isMap; 13 | 14 | private boolean isList; 15 | 16 | public Map getZsonMap() { 17 | return zsonMap; 18 | } 19 | 20 | public List getZsonList() { 21 | return zsonList; 22 | } 23 | 24 | public boolean isMap() { 25 | return isMap; 26 | } 27 | 28 | public boolean isList() { 29 | return isList; 30 | } 31 | 32 | @SuppressWarnings("unchecked") 33 | public void objectConvert(Object obj) { 34 | if (obj instanceof List) { 35 | zsonList = (List) obj; 36 | isList = true; 37 | } else if (obj instanceof Map) { 38 | zsonMap = (Map) obj; 39 | isMap = true; 40 | } 41 | /*else{ 42 | throw new ZsonException("can not convert "+ obj.getClass().getSimpleName()+" to List or Map!"); 43 | }*/ 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/parse/ZsonInfo.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.parse; 2 | 3 | public class ZsonInfo { 4 | 5 | private String element = null;//扫描出来的数据 6 | 7 | private String v = null;//如果是map,扫描出来的value 8 | 9 | private boolean isMap = false;//:后会被判定为MAP 10 | 11 | private boolean isMark = false;// 标识" 12 | 13 | private boolean isElementSeparate = false; //是不是逗号 14 | 15 | private int markIndex = 0;// 标识有多少个" 16 | 17 | private boolean needClassType = false; 18 | 19 | public String getElement() { 20 | return element; 21 | } 22 | 23 | public void setElement(String element) { 24 | this.element = element; 25 | } 26 | 27 | public String getV() { 28 | return v; 29 | } 30 | 31 | public void setV(String v) { 32 | this.v = v; 33 | } 34 | 35 | public boolean isMap() { 36 | return isMap; 37 | } 38 | 39 | public void setMap(boolean isMap) { 40 | this.isMap = isMap; 41 | } 42 | 43 | public boolean isMark() { 44 | return isMark; 45 | } 46 | 47 | public void setMark(boolean isMark) { 48 | this.isMark = isMark; 49 | } 50 | 51 | public int getMarkIndex() { 52 | return markIndex; 53 | } 54 | 55 | public void setMarkIndex(int markIndex) { 56 | this.markIndex = markIndex; 57 | } 58 | 59 | public boolean isElementSeparate() { 60 | return isElementSeparate; 61 | } 62 | 63 | public void setElementSeparate(boolean isElementSeparate) { 64 | this.isElementSeparate = isElementSeparate; 65 | } 66 | 67 | public boolean isNeedClassType() { 68 | return needClassType; 69 | } 70 | 71 | public void setNeedClassType(boolean needClassType) { 72 | this.needClassType = needClassType; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/path/ZsonCurrentPath.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.path; 2 | 3 | public class ZsonCurrentPath { 4 | 5 | private Integer index; 6 | 7 | private String key; 8 | 9 | public Integer getIndex() { 10 | return index; 11 | } 12 | 13 | public void setIndex(Integer index) { 14 | this.index = index; 15 | } 16 | 17 | public String getKey() { 18 | return key; 19 | } 20 | 21 | public void setKey(String key) { 22 | this.key = key; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/path/ZsonPath.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.path; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ZsonPath { 7 | 8 | private String path; 9 | 10 | private List paths; 11 | 12 | public String getPath() { 13 | return path; 14 | } 15 | 16 | public void setPath(String path) { 17 | this.path = path; 18 | paths = this.parsePath(path); 19 | } 20 | 21 | public boolean isAbsolutePath() { 22 | for (String p : paths) { 23 | if ("".equals(p)) { 24 | return false; 25 | } 26 | } 27 | return true; 28 | } 29 | 30 | public boolean checkPath() { 31 | if (this.isRootPath()) { 32 | return true; 33 | } 34 | if (paths == null) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | public boolean isRootPath() { 41 | return "".equals(path); 42 | } 43 | 44 | public boolean isMatchPath(String targetPath) { 45 | if (this.isAbsolutePath()) { 46 | return path.equals(targetPath); 47 | } 48 | List allPaths = this.parsePath(targetPath); 49 | if (paths == null) { 50 | return false; 51 | } 52 | int lastMatchCount = 0; 53 | //相对路径最后一部分要相同 54 | for (int i = paths.size() - 1; i >= 0; i--) { 55 | String s = paths.get(i); 56 | if ("".equals(s)) { 57 | break; 58 | } 59 | lastMatchCount++; 60 | if (allPaths.size() < lastMatchCount) { 61 | return false; 62 | } 63 | if (!s.equals(allPaths.get(allPaths.size() - lastMatchCount))) { 64 | return false; 65 | } 66 | } 67 | if (!paths.get(paths.size() - 1).equals(allPaths.get(allPaths.size() - 1))) { 68 | return false; 69 | } 70 | boolean isRelativePath = false; 71 | int rfromIndex = 0; 72 | int relativePathIndex = 0; 73 | int fromIndex = 0; 74 | int pathIndex = 0; 75 | //从开始比较,一直比到最后一个相对路径的lastMatchCount 76 | while (rfromIndex < paths.size() - lastMatchCount - 1) { 77 | String s = paths.get(rfromIndex); 78 | rfromIndex++; 79 | if ("".equals(s)) { 80 | relativePathIndex = rfromIndex; 81 | pathIndex = fromIndex; 82 | isRelativePath = true; 83 | continue; 84 | } 85 | if (!isRelativePath) { 86 | if (!allPaths.get(fromIndex).equals(s)) { 87 | return false; 88 | } else { 89 | fromIndex++; 90 | } 91 | } else { 92 | boolean matched = false; 93 | while (fromIndex < allPaths.size() - lastMatchCount - 1) { 94 | String path = allPaths.get(fromIndex); 95 | fromIndex++; 96 | if (path.equals(s)) { 97 | matched = true; 98 | isRelativePath = false; 99 | break; 100 | } else { 101 | rfromIndex = relativePathIndex + 1; 102 | fromIndex = pathIndex + 1; 103 | } 104 | } 105 | if (!matched) { 106 | return false; 107 | } 108 | } 109 | } 110 | return true; 111 | } 112 | 113 | public boolean ischildPath(String parentPath, String childPath) { 114 | String regPath = parentPath.replaceAll("\\/", "\\\\/").replaceAll("\\*", "\\\\*").replaceAll("\\[", "\\\\[").replaceAll("\\]", "\\\\]").replaceAll("\\\\/\\\\/", "(/.+)*\\\\/"); 115 | return childPath.matches(regPath + "/.+"); 116 | } 117 | 118 | private List parsePath(String path) { 119 | char[] cs = path.toCharArray(); 120 | boolean isEscapeChar = false; 121 | List paths = new ArrayList(); 122 | StringBuffer sb = new StringBuffer(); 123 | int pathSeparatorCount = 0; 124 | for (int i = 0; i < cs.length; i++) { 125 | if (i == 0 && cs[i] != '/') { 126 | return null; 127 | } 128 | if (i == cs.length - 1 && cs[i] == '/' && !isEscapeChar) { 129 | return null; 130 | } 131 | if (i == 0) { 132 | pathSeparatorCount++; 133 | continue; 134 | } 135 | if (cs[i] == '\\') { 136 | isEscapeChar = true; 137 | continue; 138 | } 139 | if (cs[i] == '/' && !isEscapeChar) { 140 | pathSeparatorCount++; 141 | paths.add(sb.toString()); 142 | sb.setLength(0); 143 | } else { 144 | pathSeparatorCount = 0; 145 | sb.append(cs[i]); 146 | } 147 | if (pathSeparatorCount > 2) { 148 | return null; 149 | } 150 | isEscapeChar = false; 151 | } 152 | paths.add(sb.toString()); 153 | return paths; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/ZsonAction.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result; 2 | 3 | public interface ZsonAction { 4 | 5 | boolean before(ZsonResult zr); 6 | 7 | void process(ZsonResult zr, Object value, String currentPath); 8 | 9 | int offset(ZsonResult zr, Object value); 10 | 11 | boolean after(ZsonResult zr); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/ZsonActionAbstract.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result; 2 | 3 | import com.zf.zson.ZSON; 4 | import com.zf.zson.ZsonUtils; 5 | import com.zf.zson.common.Utils; 6 | import com.zf.zson.object.ZsonObject; 7 | import com.zf.zson.path.ZsonCurrentPath; 8 | import com.zf.zson.result.impl.ZsonResultImpl; 9 | 10 | import java.util.Iterator; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | public abstract class ZsonActionAbstract implements ZsonAction { 15 | 16 | private int deleteFromIndex; 17 | 18 | protected void deleteZsonResultInfoChilrenKey(ZsonResultImpl zri, String key) { 19 | Iterator it = zri.getzResultInfo().getLevel().iterator(); 20 | int index = 0; 21 | boolean flag = false; 22 | while (it.hasNext()) { 23 | String level = it.next(); 24 | if (level.matches(key.replaceAll("\\.", "\\\\.") + "(\\.\\d+)*")) { 25 | if (!flag) { 26 | deleteFromIndex = index; 27 | flag = true; 28 | } 29 | it.remove(); 30 | zri.getzResultInfo().getPath().remove(index); 31 | zri.getzResultInfo().getClassTypes().remove(index); 32 | zri.getzResultInfo().getIndex().remove(level); 33 | zri.getzResultInfo().getCollections().remove(index); 34 | index--; 35 | } 36 | index++; 37 | } 38 | } 39 | 40 | protected void replaceZsonResultInfoKey(ZsonResultImpl zrNew, String targetKey, String parentPath, List handledPath, String addRootPath) { 41 | List levels = zrNew.getzResultInfo().getLevel(); 42 | Map> newIndex = Utils.getMap(zrNew.getzResultInfo().isLinked()); 43 | for (int i = 0; i < levels.size(); i++) { 44 | String key = levels.get(i); 45 | String newLevel = targetKey + levels.get(i).substring(1); 46 | levels.set(i, newLevel); 47 | List paths = zrNew.getzResultInfo().getPath(); 48 | this.updatePaths(zrNew, paths.get(i), parentPath, handledPath, addRootPath); 49 | Map> index = zrNew.getzResultInfo().getIndex(); 50 | this.updateIndexs(index, newIndex, key, targetKey); 51 | this.updateCollections(zrNew.getzResultInfo().getCollections().get(i), targetKey); 52 | } 53 | zrNew.getzResultInfo().setIndex(newIndex); 54 | } 55 | 56 | protected void recorrectIndex(ZsonResultImpl zri) { 57 | List levels = zri.getzResultInfo().getLevel(); 58 | for (int i = 0; i < levels.size(); i++) { 59 | zri.getzResultInfo().getIndex().get(levels.get(i)).put(ZsonUtils.INDEX, i); 60 | } 61 | } 62 | 63 | private void updatePaths(ZsonResultImpl zrNew, Object paths, String parentPath, List handledPath, String addRootPath) { 64 | ZsonObject pathObj = new ZsonObject(); 65 | pathObj.objectConvert(paths); 66 | if (pathObj.isMap()) { 67 | Map pathMap = pathObj.getZsonMap(); 68 | for (String k : pathMap.keySet()) { 69 | String newPath = parentPath + pathMap.get(k); 70 | pathMap.put(k, newPath); 71 | if (handledPath != null) { 72 | if (zrNew.getzPath().ischildPath(addRootPath, newPath)) { 73 | handledPath.add(newPath); 74 | } 75 | } 76 | } 77 | } else if (pathObj.isList()) { 78 | List pathList = pathObj.getZsonList(); 79 | for (int i = 0; i < pathList.size(); i++) { 80 | String newPath = parentPath + pathList.get(i); 81 | pathList.set(i, newPath); 82 | if (handledPath != null) { 83 | if (zrNew.getzPath().ischildPath(addRootPath, newPath)) { 84 | handledPath.add(newPath); 85 | } 86 | } 87 | } 88 | } 89 | } 90 | 91 | private void updateIndexs(Map> index, Map> newIndex, String key, String targetKey) { 92 | Map indexInfo = index.get(key); 93 | //indexInfo.put(ZsonUtils.INDEX, indexInfo.get(ZsonUtils.INDEX)+addIndex); 94 | String newKey = targetKey + key.substring(1); 95 | newIndex.put(newKey, indexInfo); 96 | } 97 | 98 | private void updateCollections(Object collection, String targetKey) { 99 | ZsonObject collectionObj = new ZsonObject(); 100 | collectionObj.objectConvert(collection); 101 | if (collectionObj.isMap()) { 102 | Map collectionMap = collectionObj.getZsonMap(); 103 | for (String k : collectionMap.keySet()) { 104 | ZsonObject cElementObj = new ZsonObject(); 105 | cElementObj.objectConvert(collectionMap.get(k)); 106 | if (cElementObj.isMap()) { 107 | Map cMap = cElementObj.getZsonMap(); 108 | cMap.put(ZsonUtils.LINK, targetKey + cMap.get(ZsonUtils.LINK).substring(1)); 109 | } else if (cElementObj.isList()) { 110 | List cList = cElementObj.getZsonList(); 111 | cList.set(0, targetKey + cList.get(0).substring(1)); 112 | } 113 | } 114 | } else if (collectionObj.isList()) { 115 | List collectionList = collectionObj.getZsonList(); 116 | for (Object cObj : collectionList) { 117 | ZsonObject cElementObj = new ZsonObject(); 118 | cElementObj.objectConvert(cObj); 119 | if (cElementObj.isMap()) { 120 | Map cMap = cElementObj.getZsonMap(); 121 | cMap.put(ZsonUtils.LINK, targetKey + cMap.get(ZsonUtils.LINK).substring(1)); 122 | } else if (cElementObj.isList()) { 123 | List cList = cElementObj.getZsonList(); 124 | cList.set(0, targetKey + cList.get(0).substring(1)); 125 | } 126 | } 127 | } 128 | } 129 | 130 | protected void addNewResultToSourceResult(ZsonResultImpl source, ZsonResultImpl newResult) { 131 | source.getzResultInfo().getLevel().addAll(deleteFromIndex, newResult.getzResultInfo().getLevel()); 132 | source.getzResultInfo().getPath().addAll(deleteFromIndex, newResult.getzResultInfo().getPath()); 133 | source.getzResultInfo().getClassTypes().addAll(deleteFromIndex, newResult.getzResultInfo().getClassTypes()); 134 | source.getzResultInfo().getIndex().putAll(newResult.getzResultInfo().getIndex()); 135 | source.getzResultInfo().getCollections().addAll(deleteFromIndex, newResult.getzResultInfo().getCollections()); 136 | } 137 | 138 | protected ZsonCurrentPath setKeyOrIndexByPath(ZsonResultImpl zri, String path) { 139 | ZsonCurrentPath zcp = new ZsonCurrentPath(); 140 | List paths = zri.getzResultInfo().getPath(); 141 | for (Object pathObject : paths) { 142 | ZsonObject pathObj = new ZsonObject(); 143 | pathObj.objectConvert(pathObject); 144 | if (pathObj.isList()) { 145 | int index = 0; 146 | for (String p : pathObj.getZsonList()) { 147 | if (p.equals(path)) { 148 | zcp.setIndex(index); 149 | return zcp; 150 | } 151 | index++; 152 | } 153 | } else if (pathObj.isMap()) { 154 | for (String k : pathObj.getZsonMap().keySet()) { 155 | if (pathObj.getZsonMap().get(k).equals(path)) { 156 | zcp.setKey(k); 157 | return zcp; 158 | } 159 | } 160 | } 161 | } 162 | return null; 163 | } 164 | 165 | protected String getKeyByPath(ZsonResultImpl zri, String path) { 166 | List paths = zri.getzResultInfo().getPath(); 167 | int index = 0; 168 | for (Object pathObject : paths) { 169 | ZsonObject pathObj = new ZsonObject(); 170 | pathObj.objectConvert(pathObject); 171 | if (pathObj.isList()) { 172 | for (String p : pathObj.getZsonList()) { 173 | if (p.equals(path)) { 174 | return zri.getzResultInfo().getLevel().get(index); 175 | } 176 | } 177 | } else if (pathObj.isMap()) { 178 | for (String p : pathObj.getZsonMap().values()) { 179 | if (p.equals(path)) { 180 | return zri.getzResultInfo().getLevel().get(index); 181 | } 182 | } 183 | } 184 | index++; 185 | } 186 | return null; 187 | } 188 | 189 | protected String getParentPath(String currentPath) { 190 | String parentPath = currentPath.substring(0, currentPath.lastIndexOf('/')); 191 | return parentPath; 192 | } 193 | 194 | protected Object getActionObject(ZsonResultImpl zri, Object str) { 195 | Object actionValue = str; 196 | try { 197 | ZsonResultImpl zra = (ZsonResultImpl) ZSON.parseJson(str.toString()); 198 | actionValue = zra.getResultByKey(ZsonUtils.BEGIN_KEY); 199 | } catch (Exception e) { 200 | 201 | } 202 | return actionValue; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/ZsonResult.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | 7 | public interface ZsonResult { 8 | 9 | boolean isValid(); 10 | 11 | Object getResult(); 12 | 13 | Object getValue(String path); 14 | 15 | Object getValue(); 16 | 17 | List getValues(String path); 18 | 19 | String getString(String path); 20 | 21 | int getInteger(String path); 22 | 23 | long getLong(String path); 24 | 25 | double getDouble(String path); 26 | 27 | float getFloat(String path); 28 | 29 | boolean getBoolean(String path); 30 | 31 | void addValue(String path, Object json); 32 | 33 | void deleteValue(String path); 34 | 35 | void updateValue(String path, Object json); 36 | 37 | List getPaths(); 38 | 39 | Map> getClassTypes(); 40 | 41 | boolean validateJsonClassTypes(String baseJson); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/ZsonResultAbstract.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result; 2 | 3 | import com.zf.zson.ZSON; 4 | import com.zf.zson.ZsonUtils; 5 | import com.zf.zson.common.Utils; 6 | import com.zf.zson.object.ZsonObject; 7 | import com.zf.zson.path.ZsonPath; 8 | import com.zf.zson.result.impl.ZsonResultImpl; 9 | import com.zf.zson.result.info.ZsonResultInfo; 10 | import com.zf.zson.result.utils.ZsonResultRestore; 11 | import com.zf.zson.result.utils.ZsonResultToString; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.Set; 17 | 18 | public abstract class ZsonResultAbstract implements ZsonResult { 19 | 20 | protected ZsonResultInfo zResultInfo; 21 | 22 | protected ZsonPath zPath; 23 | 24 | protected ZsonResultToString zsonResultToString; 25 | 26 | protected ZsonResultRestore zsonResultRestore; 27 | 28 | public ZsonResultAbstract(boolean linked) { 29 | zResultInfo = new ZsonResultInfo(linked); 30 | zPath = new ZsonPath(); 31 | zsonResultToString = new ZsonResultToString(); 32 | zsonResultRestore = new ZsonResultRestore(this); 33 | } 34 | 35 | protected abstract void checkValid(); 36 | 37 | public ZsonResultInfo getzResultInfo() { 38 | return zResultInfo; 39 | } 40 | 41 | public ZsonPath getzPath() { 42 | return zPath; 43 | } 44 | 45 | public ZsonResultToString getZsonResultToString() { 46 | return zsonResultToString; 47 | } 48 | 49 | public ZsonResultRestore getZsonResultRestore() { 50 | return zsonResultRestore; 51 | } 52 | 53 | public String getElementKey(Object value) { 54 | ZsonObject keyObj = new ZsonObject(); 55 | keyObj.objectConvert(value); 56 | String key; 57 | if (keyObj.isMap()) { 58 | key = keyObj.getZsonMap().get(ZsonUtils.LINK); 59 | } else if (keyObj.isList()) { 60 | key = keyObj.getZsonList().get(0); 61 | } else { 62 | key = null; 63 | } 64 | return key; 65 | } 66 | 67 | /** 68 | * 将在collections中获取到的值给重新的还原,并返回出去 69 | * 70 | * @param value 71 | * @return 72 | */ 73 | public Object getCollectionsObjectAndRestore(Object value) { 74 | if (value instanceof Map || value instanceof List) { 75 | String key = this.getElementKey(value); 76 | Map elementStatus = zResultInfo.getIndex().get(key); 77 | Object elementObj = zResultInfo.getCollections().get(elementStatus.get(ZsonUtils.INDEX)); 78 | value = zsonResultToString.toJsonString(zsonResultRestore.restoreObject(elementObj)); 79 | } else if (value instanceof String) { 80 | value = ZsonUtils.convert((String) value); 81 | } 82 | return value; 83 | } 84 | 85 | public Object getResultByKey(String key) { 86 | Map elementStatus = zResultInfo.getIndex().get(key); 87 | Object obj = zResultInfo.getCollections().get(elementStatus.get(ZsonUtils.INDEX)); 88 | return zsonResultRestore.restoreObject(obj); 89 | } 90 | 91 | public List getPaths() { 92 | List list = new ArrayList(); 93 | for (Object pathObj : zResultInfo.getPath()) { 94 | ZsonObject zo = new ZsonObject(); 95 | zo.objectConvert(pathObj); 96 | if (zo.isMap()) { 97 | list.addAll(zo.getZsonMap().values()); 98 | } else { 99 | list.addAll(zo.getZsonList()); 100 | } 101 | } 102 | return list; 103 | } 104 | 105 | @Override 106 | public Map> getClassTypes() { 107 | Map> classTypes = Utils.getMap(zResultInfo.isLinked()); 108 | for (int i = 0; i < zResultInfo.getPath().size(); i++) { 109 | ZsonObject zoPath = new ZsonObject(); 110 | zoPath.objectConvert(zResultInfo.getPath().get(i)); 111 | ZsonObject> zoClass = new ZsonObject>(); 112 | zoClass.objectConvert(zResultInfo.getClassTypes().get(i)); 113 | if (zoPath.isMap()) { 114 | for (String key : zoPath.getZsonMap().keySet()) { 115 | classTypes.put(zoPath.getZsonMap().get(key), zoClass.getZsonMap().get(key)); 116 | } 117 | } else { 118 | for (int j = 0; j < zoPath.getZsonList().size(); j++) { 119 | classTypes.put(zoPath.getZsonList().get(j), zoClass.getZsonList().get(j)); 120 | } 121 | } 122 | } 123 | return classTypes; 124 | } 125 | 126 | @Override 127 | public boolean validateJsonClassTypes(String baseJson) { 128 | Map> cs = this.getClassTypes(); 129 | ZsonResult bzr = ZSON.parseJson(baseJson, zResultInfo.isLinked()); 130 | Map> bcs = bzr.getClassTypes(); 131 | if (bcs.size() == 0) { 132 | return this.getResult().getClass().equals(bzr.getResult().getClass()); 133 | } 134 | for (String bckey : bcs.keySet()) { 135 | List keys = this.getSameLevelJsonPath(cs.keySet(), bckey); 136 | if(keys.size()==0){ 137 | return false; 138 | } 139 | for (String key : keys) { 140 | if(key.equals(bckey) || !bcs.keySet().contains(key)){ 141 | if(!cs.get(key).equals(Object.class) && !bcs.get(bckey).equals(Object.class) && !cs.get(key).equals(bcs.get(bckey))){ 142 | return false; 143 | } 144 | } 145 | } 146 | } 147 | return true; 148 | } 149 | 150 | private List getSameLevelJsonPath(Set set, String key){ 151 | int lastIndex1 = key.lastIndexOf("/*["); 152 | int lastIndex2 = key.lastIndexOf(']'); 153 | String replace = key.substring(0,lastIndex1)+"/*[\\d+]"+key.substring(lastIndex2+1); 154 | String regKey = replace.replaceAll("\\*", "\\\\*").replaceAll("\\[", "\\\\["); 155 | List list = new ArrayList(); 156 | for (String s : set) { 157 | if(s.matches(regKey)){ 158 | list.add(s); 159 | } 160 | } 161 | return list; 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/impl/ZsonAdd.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.impl; 2 | 3 | import com.zf.zson.ZSON; 4 | import com.zf.zson.ZsonUtils; 5 | import com.zf.zson.object.ZsonObject; 6 | import com.zf.zson.result.ZsonActionAbstract; 7 | import com.zf.zson.result.ZsonResult; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public class ZsonAdd extends ZsonActionAbstract { 14 | 15 | private Object addJson; 16 | 17 | private String addKey; 18 | 19 | private Integer addIndex; 20 | 21 | private String addRootPath; 22 | 23 | private List handledPath = new ArrayList(); 24 | 25 | public void setAddJson(Object addJson) { 26 | this.addJson = addJson; 27 | } 28 | 29 | public void setAddKey(String addKey) { 30 | this.addKey = addKey; 31 | } 32 | 33 | public void setAddIndex(Integer addIndex) { 34 | this.addIndex = addIndex; 35 | } 36 | 37 | public void process(ZsonResult zr, Object value, String currentPath) { 38 | if (handledPath.contains(currentPath)) { 39 | return; 40 | } 41 | ZsonResultImpl zri = (ZsonResultImpl) zr; 42 | String key = zri.getElementKey(value); 43 | if (key == null) { 44 | return; 45 | } 46 | //String parentPath = this.getParentPath(zri, key); 47 | Object pathValue = zri.getResultByKey(key); 48 | ZsonObject valueByKeyObj = new ZsonObject(); 49 | valueByKeyObj.objectConvert(pathValue); 50 | if ((addIndex != null && valueByKeyObj.isList()) || (addKey != null && valueByKeyObj.isMap())) { 51 | Object addObj = null; 52 | if (addIndex != null && valueByKeyObj.isList()) { 53 | List pathValueList = valueByKeyObj.getZsonList(); 54 | Object actionValue = this.getActionObject(zri, addJson); 55 | pathValueList.add(addIndex, actionValue); 56 | addRootPath = currentPath + "/*[" + addIndex + "]"; 57 | addObj = pathValueList; 58 | 59 | } else if (addKey != null && valueByKeyObj.isMap()) { 60 | Map pathValueMap = valueByKeyObj.getZsonMap(); 61 | Object actionValue = this.getActionObject(zri, addJson); 62 | pathValueMap.put(addKey, actionValue); 63 | addRootPath = currentPath + "/" + addKey; 64 | addObj = pathValueMap; 65 | } 66 | handledPath.add(currentPath); 67 | handledPath.add(addRootPath); 68 | ZsonResultImpl zrNew = (ZsonResultImpl) ZSON.parseJson(ZSON.toJsonString(addObj), zri.getzResultInfo().isLinked()); 69 | this.deleteZsonResultInfoChilrenKey(zri, key); 70 | this.replaceZsonResultInfoKey(zrNew, key, currentPath, handledPath, addRootPath); 71 | this.addNewResultToSourceResult(zri, zrNew); 72 | this.recorrectIndex(zri); 73 | } 74 | } 75 | 76 | @Override 77 | public int offset(ZsonResult zr, Object value) { 78 | return 0; 79 | } 80 | 81 | @Override 82 | public boolean before(ZsonResult zr) { 83 | ZsonResultImpl zri = (ZsonResultImpl) zr; 84 | if (zri.getzPath().isRootPath()) { 85 | Object pathValue = zri.getResultByKey(ZsonUtils.BEGIN_KEY); 86 | ZsonObject valueByKeyObj = new ZsonObject(); 87 | valueByKeyObj.objectConvert(pathValue); 88 | if ((addIndex != null && valueByKeyObj.isList()) || (addKey != null && valueByKeyObj.isMap())) { 89 | Object addObj = null; 90 | if (addIndex != null && valueByKeyObj.isList()) { 91 | List pathValueList = valueByKeyObj.getZsonList(); 92 | Object actionValue = this.getActionObject(zri, addJson); 93 | pathValueList.add(addIndex, actionValue); 94 | addObj = pathValueList; 95 | 96 | } else if (addKey != null && valueByKeyObj.isMap()) { 97 | Map pathValueMap = valueByKeyObj.getZsonMap(); 98 | Object actionValue = this.getActionObject(zri, addJson); 99 | pathValueMap.put(addKey, actionValue); 100 | addObj = pathValueMap; 101 | } 102 | ZsonResultImpl zrNew = (ZsonResultImpl) ZSON.parseJson(zri.getZsonResultToString().toJsonString(addObj), zri.getzResultInfo().isLinked()); 103 | zri.getzResultInfo().setCollections(zrNew.getzResultInfo().getCollections()); 104 | zri.getzResultInfo().setIndex(zrNew.getzResultInfo().getIndex()); 105 | zri.getzResultInfo().setLevel(zrNew.getzResultInfo().getLevel()); 106 | zri.getzResultInfo().setPath(zrNew.getzResultInfo().getPath()); 107 | zri.getzResultInfo().setClassTypes(zrNew.getzResultInfo().getClassTypes()); 108 | } 109 | return false; 110 | } 111 | return true; 112 | } 113 | 114 | @Override 115 | public boolean after(ZsonResult zr) { 116 | return false; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/impl/ZsonDelete.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.impl; 2 | 3 | import com.zf.zson.ZSON; 4 | import com.zf.zson.object.ZsonObject; 5 | import com.zf.zson.path.ZsonCurrentPath; 6 | import com.zf.zson.result.ZsonActionAbstract; 7 | import com.zf.zson.result.ZsonResult; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class ZsonDelete extends ZsonActionAbstract { 13 | 14 | private boolean deleted = false; 15 | 16 | public void process(ZsonResult zr, Object value, String currentPath) { 17 | ZsonResultImpl zri = (ZsonResultImpl) zr; 18 | String ckey = zri.getElementKey(value); 19 | ZsonCurrentPath zcp = this.setKeyOrIndexByPath(zri, currentPath); 20 | String key; 21 | key = this.getKeyByPath(zri, currentPath); 22 | Object element = zri.getResultByKey(key); 23 | ZsonObject parentObj = new ZsonObject(); 24 | parentObj.objectConvert(element); 25 | if ((zcp.getIndex() != null && parentObj.isList()) || (zcp.getKey() != null && parentObj.isMap())) { 26 | Object addObj = null; 27 | if (zcp.getIndex() != null && parentObj.isList()) { 28 | List pathValueList = parentObj.getZsonList(); 29 | pathValueList.remove((int) zcp.getIndex()); 30 | addObj = pathValueList; 31 | 32 | } else if (zcp.getKey() != null && parentObj.isMap()) { 33 | Map pathValueMap = parentObj.getZsonMap(); 34 | pathValueMap.remove(zcp.getKey()); 35 | addObj = pathValueMap; 36 | } 37 | if (ckey != null) { 38 | deleted = true; 39 | } 40 | ZsonResultImpl zrNew = (ZsonResultImpl) ZSON.parseJson(ZSON.toJsonString(addObj), zri.getzResultInfo().isLinked()); 41 | this.deleteZsonResultInfoChilrenKey(zri, key); 42 | this.replaceZsonResultInfoKey(zrNew, key, this.getParentPath(currentPath), null, null); 43 | this.addNewResultToSourceResult(zri, zrNew); 44 | this.recorrectIndex(zri); 45 | } 46 | } 47 | 48 | @Override 49 | public int offset(ZsonResult zr, Object value) { 50 | if (deleted) { 51 | return -1; 52 | } else { 53 | return 0; 54 | } 55 | //return 0; 56 | } 57 | 58 | @Override 59 | public boolean before(ZsonResult zr) { 60 | return true; 61 | } 62 | 63 | @Override 64 | public boolean after(ZsonResult zr) { 65 | return false; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/impl/ZsonResultImpl.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.impl; 2 | 3 | import com.zf.zson.ZsonUtils; 4 | import com.zf.zson.exception.ZsonException; 5 | import com.zf.zson.object.ZsonObject; 6 | import com.zf.zson.result.ZsonAction; 7 | import com.zf.zson.result.ZsonResultAbstract; 8 | 9 | import java.math.BigDecimal; 10 | import java.util.Collection; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | public class ZsonResultImpl extends ZsonResultAbstract { 15 | 16 | public ZsonResultImpl(boolean linked) { 17 | super(linked); 18 | } 19 | 20 | public boolean isValid() { 21 | if (!zResultInfo.isValid() || zResultInfo.getCollections().size() == 0) { 22 | return false; 23 | } 24 | if (!zResultInfo.isAllFinished()) { 25 | Collection> values = zResultInfo.getIndex().values(); 26 | for (Map map : values) { 27 | if (map.get(ZsonUtils.STATUS) == 0) { 28 | zResultInfo.setValid(false); 29 | zResultInfo.setAllFinished(true); 30 | return zResultInfo.isValid(); 31 | } 32 | } 33 | } 34 | return zResultInfo.isValid(); 35 | } 36 | 37 | public void checkValid() { 38 | if (!this.isValid()) { 39 | throw new ZsonException(ZsonUtils.JSON_NOT_VALID); 40 | } 41 | } 42 | 43 | private void beforeHandle(String path) { 44 | this.checkValid(); 45 | zPath.setPath(path); 46 | if (!zPath.checkPath()) { 47 | throw new ZsonException("path is not valid!"); 48 | } 49 | } 50 | 51 | private void resultHandle(ZsonAction za, String path, boolean isSingleResult) { 52 | this.beforeHandle(path); 53 | if (!za.before(this)) { 54 | return; 55 | } 56 | if (zPath.isAbsolutePath()) { 57 | isSingleResult = true; 58 | } 59 | //List levels = zResultInfo.getLevel(); 60 | for (int i = 0; i < zResultInfo.getLevel().size(); i++) { 61 | ZsonObject pathObject = new ZsonObject(); 62 | pathObject.objectConvert(zResultInfo.getPath().get(i)); 63 | if (pathObject.isList()) { 64 | //List pathList = pathObject.getZsonList(); 65 | for (int j = 0; j < pathObject.getZsonList().size(); j++) { 66 | if (zPath.isMatchPath(pathObject.getZsonList().get(j))) { 67 | ZsonObject resultObject = new ZsonObject(); 68 | resultObject.objectConvert(zResultInfo.getCollections().get(i)); 69 | if (!(resultObject.isList())) { 70 | throw new ZsonException("parse json error!"); 71 | } 72 | List resultList = resultObject.getZsonList(); 73 | Object value = resultList.get(j); 74 | za.process(this, value, pathObject.getZsonList().get(j)); 75 | i += za.offset(this, value); 76 | if (isSingleResult) { 77 | za.after(this); 78 | return; 79 | } 80 | } 81 | } 82 | } else if (pathObject.isMap()) { 83 | //Map pathMap = pathObject.getZsonMap(); 84 | for (String k : pathObject.getZsonMap().keySet()) { 85 | if (zPath.isMatchPath(pathObject.getZsonMap().get(k))) { 86 | ZsonObject resultObject = new ZsonObject(); 87 | resultObject.objectConvert(zResultInfo.getCollections().get(i)); 88 | if (!(resultObject.isMap())) { 89 | throw new ZsonException("parse json error!"); 90 | } 91 | Map resultMap = resultObject.getZsonMap(); 92 | Object value = resultMap.get(k); 93 | za.process(this, value, pathObject.getZsonMap().get(k)); 94 | i += za.offset(this, value); 95 | if (isSingleResult) { 96 | za.after(this); 97 | return; 98 | } 99 | } 100 | } 101 | } 102 | } 103 | if (isSingleResult) { 104 | throw new ZsonException("path is not valid!"); 105 | } 106 | za.after(this); 107 | } 108 | 109 | public Object getValue(String path) { 110 | ZsonRetrieve zre = new ZsonRetrieve(); 111 | this.resultHandle(zre, path, true); 112 | return zre.getResult().get(0); 113 | } 114 | 115 | @Override 116 | public Object getValue() { 117 | ZsonRetrieve zre = new ZsonRetrieve(); 118 | this.resultHandle(zre, "", true); 119 | return zre.getResult().get(0); 120 | } 121 | 122 | public List getValues(String path) { 123 | ZsonRetrieve zre = new ZsonRetrieve(); 124 | this.resultHandle(zre, path, false); 125 | return zre.getResult(); 126 | } 127 | 128 | @Override 129 | public int getInteger(String path) { 130 | Object obj = this.getValue(path); 131 | if (obj instanceof BigDecimal) { 132 | return ((BigDecimal) obj).intValue(); 133 | } else { 134 | throw new ZsonException("can not get int with path: " + path); 135 | } 136 | } 137 | 138 | @Override 139 | public long getLong(String path) { 140 | Object obj = this.getValue(path); 141 | if (obj instanceof BigDecimal) { 142 | return ((BigDecimal) obj).longValue(); 143 | } else { 144 | throw new ZsonException("can not get long with path: " + path); 145 | } 146 | } 147 | 148 | @Override 149 | public double getDouble(String path) { 150 | Object obj = this.getValue(path); 151 | if (obj instanceof BigDecimal) { 152 | return ((BigDecimal) obj).doubleValue(); 153 | } else { 154 | throw new ZsonException("can not get double with path: " + path); 155 | } 156 | } 157 | 158 | @Override 159 | public float getFloat(String path) { 160 | Object obj = this.getValue(path); 161 | if (obj instanceof BigDecimal) { 162 | return ((BigDecimal) obj).floatValue(); 163 | } else { 164 | throw new ZsonException("can not get float with path: " + path); 165 | } 166 | } 167 | 168 | @Override 169 | public boolean getBoolean(String path) { 170 | Object obj = this.getValue(path); 171 | if (obj instanceof Boolean) { 172 | return (Boolean) obj; 173 | } else { 174 | throw new ZsonException("can not get boolean with path: " + path); 175 | } 176 | } 177 | 178 | @Override 179 | public String getString(String path) { 180 | Object obj = this.getValue(path); 181 | if (obj instanceof String) { 182 | return (String) obj; 183 | } else { 184 | throw new ZsonException("can not get String with path: " + path); 185 | } 186 | } 187 | 188 | @Override 189 | public void addValue(String path, Object json) { 190 | ZsonAdd add = new ZsonAdd(); 191 | add.setAddJson(json); 192 | String key = path.substring(path.lastIndexOf("/") + 1); 193 | if (key.matches("\\*\\[\\d+\\]")) { 194 | add.setAddIndex(Integer.parseInt(key.replaceFirst("\\*\\[(\\d+)\\]", "$1"))); 195 | } else if ("".equals(key)) { 196 | throw new ZsonException("path is not valid!"); 197 | } else { 198 | add.setAddKey(key); 199 | } 200 | path = path.substring(0, path.lastIndexOf("/")).replaceFirst("(.*?)/*$", "$1"); 201 | this.resultHandle(add, path, false); 202 | } 203 | 204 | @Override 205 | public Object getResult() { 206 | return this.getResultByKey(ZsonUtils.BEGIN_KEY); 207 | } 208 | 209 | @Override 210 | public void deleteValue(String path) { 211 | ZsonDelete delete = new ZsonDelete(); 212 | this.resultHandle(delete, path, false); 213 | } 214 | 215 | @Override 216 | public void updateValue(String path, Object json) { 217 | ZsonUpdate update = new ZsonUpdate(); 218 | update.setUpdateJson(json); 219 | this.resultHandle(update, path, false); 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/impl/ZsonRetrieve.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.impl; 2 | 3 | import com.zf.zson.ZsonUtils; 4 | import com.zf.zson.result.ZsonAction; 5 | import com.zf.zson.result.ZsonResult; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class ZsonRetrieve implements ZsonAction { 11 | 12 | private List result = new ArrayList(); 13 | 14 | public List getResult() { 15 | return result; 16 | } 17 | 18 | @Override 19 | public void process(ZsonResult zr, Object value, String currentPath) { 20 | ZsonResultImpl zri = (ZsonResultImpl) zr; 21 | result.add(zri.getCollectionsObjectAndRestore(value)); 22 | } 23 | 24 | @Override 25 | public int offset(ZsonResult zr, Object value) { 26 | return 0; 27 | } 28 | 29 | @Override 30 | public boolean before(ZsonResult zr) { 31 | ZsonResultImpl zri = (ZsonResultImpl) zr; 32 | if (zri.getzPath().isRootPath()) { 33 | result.add(zri.getZsonResultToString().toJsonString(zri.getResultByKey(ZsonUtils.BEGIN_KEY))); 34 | return false; 35 | } 36 | return true; 37 | } 38 | 39 | @Override 40 | public boolean after(ZsonResult zr) { 41 | return false; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/impl/ZsonUpdate.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.impl; 2 | 3 | import com.zf.zson.ZSON; 4 | import com.zf.zson.object.ZsonObject; 5 | import com.zf.zson.path.ZsonCurrentPath; 6 | import com.zf.zson.result.ZsonActionAbstract; 7 | import com.zf.zson.result.ZsonResult; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public class ZsonUpdate extends ZsonActionAbstract { 14 | 15 | private Object updateJson; 16 | 17 | private List handledPath = new ArrayList(); 18 | 19 | public void setUpdateJson(Object updateJson) { 20 | this.updateJson = updateJson; 21 | } 22 | 23 | @Override 24 | public void process(ZsonResult zr, Object value, String currentPath) { 25 | if (handledPath.contains(currentPath)) { 26 | return; 27 | } 28 | ZsonResultImpl zri = (ZsonResultImpl) zr; 29 | ZsonCurrentPath zcp = this.setKeyOrIndexByPath(zri, currentPath); 30 | String key; 31 | key = this.getKeyByPath(zri, currentPath); 32 | Object element = zri.getResultByKey(key); 33 | ZsonObject parentObj = new ZsonObject(); 34 | parentObj.objectConvert(element); 35 | if ((zcp.getIndex() != null && parentObj.isList()) || (zcp.getKey() != null && parentObj.isMap())) { 36 | Object updateObj = null; 37 | if (zcp.getIndex() != null && parentObj.isList()) { 38 | List pathValueList = parentObj.getZsonList(); 39 | pathValueList.set((int) zcp.getIndex(), this.getActionObject(zri, updateJson)); 40 | updateObj = pathValueList; 41 | 42 | } else if (zcp.getKey() != null && parentObj.isMap()) { 43 | Map pathValueMap = parentObj.getZsonMap(); 44 | pathValueMap.put(zcp.getKey(), this.getActionObject(zri, updateJson)); 45 | updateObj = pathValueMap; 46 | } 47 | ZsonResultImpl zrNew = (ZsonResultImpl) ZSON.parseJson(ZSON.toJsonString(updateObj), zri.getzResultInfo().isLinked()); 48 | this.deleteZsonResultInfoChilrenKey(zri, key); 49 | this.replaceZsonResultInfoKey(zrNew, key, this.getParentPath(currentPath), handledPath, currentPath); 50 | this.addNewResultToSourceResult(zri, zrNew); 51 | this.recorrectIndex(zri); 52 | } 53 | } 54 | 55 | @Override 56 | public int offset(ZsonResult zr, Object value) { 57 | return 0; 58 | } 59 | 60 | @Override 61 | public boolean before(ZsonResult zr) { 62 | return true; 63 | } 64 | 65 | @Override 66 | public boolean after(ZsonResult zr) { 67 | return false; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/info/ZsonResultInfo.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.info; 2 | 3 | import com.zf.zson.common.Utils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class ZsonResultInfo { 10 | 11 | /** 12 | * 标识json是否是一个合格的JSON串及解析是否全部解析完成 13 | */ 14 | private boolean valid = true; 15 | 16 | private boolean linked; 17 | 18 | /** 19 | * 存放解析JSON过程中所有的LIST与MAP 20 | */ 21 | private List collections = new ArrayList(); 22 | 23 | /** 24 | * index的最外层MAP的key为1 1.1 1.1.2这种形式,表示JSON的层次结构 25 | * 里面的MAP为当前层次中的数据结构类型与状态,比如{"type":0,"status":0,"index":0}, 26 | * type有0,1,0表示MAP, 1表示LIST, 27 | * status有0,1,0表示没有解析完成,1表示已解析完成 28 | * index指对象在collections中的index 29 | */ 30 | private Map> index; 31 | 32 | /** 33 | * 标识json解析是否全部解析完成 34 | */ 35 | private boolean allFinished = false; 36 | 37 | /** 38 | * 存放JSON的层次结构比如1 1.1 1.1.2 39 | */ 40 | private List level = new ArrayList(); 41 | 42 | /** 43 | * 存放JSON的path 44 | */ 45 | private List path = new ArrayList(); 46 | 47 | /** 48 | * 存放JSON的数据类型 49 | */ 50 | private List classTypes = new ArrayList(); 51 | 52 | public ZsonResultInfo(boolean linked) { 53 | this.linked = linked; 54 | index = Utils.getMap(linked); 55 | } 56 | 57 | public boolean isValid() { 58 | return valid; 59 | } 60 | 61 | public void setValid(boolean valid) { 62 | this.valid = valid; 63 | } 64 | 65 | public List getCollections() { 66 | return collections; 67 | } 68 | 69 | public void setCollections(List collections) { 70 | this.collections = collections; 71 | } 72 | 73 | public Map> getIndex() { 74 | return index; 75 | } 76 | 77 | public void setIndex(Map> index) { 78 | this.index = index; 79 | } 80 | 81 | public boolean isAllFinished() { 82 | return allFinished; 83 | } 84 | 85 | public void setAllFinished(boolean allFinished) { 86 | this.allFinished = allFinished; 87 | } 88 | 89 | public List getLevel() { 90 | return level; 91 | } 92 | 93 | public void setLevel(List level) { 94 | this.level = level; 95 | } 96 | 97 | public List getPath() { 98 | return path; 99 | } 100 | 101 | public void setPath(List path) { 102 | this.path = path; 103 | } 104 | 105 | public List getClassTypes() { 106 | return classTypes; 107 | } 108 | 109 | public void setClassTypes(List classTypes) { 110 | this.classTypes = classTypes; 111 | } 112 | 113 | public boolean isLinked() { 114 | return linked; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/utils/ZsonResultRestore.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.utils; 2 | 3 | import com.zf.zson.ZsonUtils; 4 | import com.zf.zson.common.Utils; 5 | import com.zf.zson.object.ZsonObject; 6 | import com.zf.zson.result.ZsonResultAbstract; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class ZsonResultRestore { 13 | 14 | private ZsonResultAbstract zsonResultAbstract; 15 | 16 | public ZsonResultRestore(ZsonResultAbstract zsonResultAbstract) { 17 | this.zsonResultAbstract = zsonResultAbstract; 18 | } 19 | 20 | public Object restoreObject(Object obj) { 21 | ZsonObject objR = new ZsonObject(); 22 | objR.objectConvert(obj); 23 | if (objR.isMap()) { 24 | return this.restoreMap(objR.getZsonMap()); 25 | } else if (objR.isList()) { 26 | return this.restoreList(objR.getZsonList()); 27 | } else { 28 | return obj; 29 | } 30 | } 31 | 32 | private Map restoreMap(Map map) { 33 | Map restore = Utils.getMap(zsonResultAbstract.getzResultInfo().isLinked()); 34 | for (String mapKey : map.keySet()) { 35 | Object mapValue = map.get(mapKey); 36 | if (mapValue instanceof Map || mapValue instanceof List) { 37 | String key = zsonResultAbstract.getElementKey(mapValue); 38 | Map elementStatus = zsonResultAbstract.getzResultInfo().getIndex().get(key); 39 | Object elementObj = zsonResultAbstract.getzResultInfo().getCollections().get(elementStatus.get(ZsonUtils.INDEX)); 40 | restore.put(mapKey, this.restoreObject(elementObj)); 41 | } else { 42 | restore.put(mapKey, mapValue); 43 | } 44 | } 45 | return restore; 46 | } 47 | 48 | private List restoreList(List list) { 49 | List restore = new ArrayList(); 50 | for (Object e : list) { 51 | if (e instanceof Map || e instanceof List) { 52 | String key = zsonResultAbstract.getElementKey(e); 53 | Map elementStatus = zsonResultAbstract.getzResultInfo().getIndex().get(key); 54 | Object elementObj = zsonResultAbstract.getzResultInfo().getCollections().get(elementStatus.get(ZsonUtils.INDEX)); 55 | restore.add(this.restoreObject(elementObj)); 56 | } else { 57 | restore.add(e); 58 | } 59 | } 60 | return restore; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/zf/zson/result/utils/ZsonResultToString.java: -------------------------------------------------------------------------------- 1 | package com.zf.zson.result.utils; 2 | 3 | import com.zf.zson.ZsonUtils; 4 | import com.zf.zson.exception.ZsonException; 5 | import com.zf.zson.object.ZsonObject; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class ZsonResultToString { 11 | 12 | private String listToString(List list) { 13 | StringBuffer sb = new StringBuffer(); 14 | sb.append(ZsonUtils.jsonListBegin); 15 | int index = 0; 16 | if (list != null) { 17 | for (Object element : list) { 18 | if (index != 0) { 19 | sb.append(ZsonUtils.jsonElementConnector); 20 | } 21 | if (element instanceof Map || element instanceof List) { 22 | String mapString = this.toJsonString(element); 23 | sb.append(mapString); 24 | } else if (element instanceof String) { 25 | sb.append(ZsonUtils.jsonStringBegin); 26 | sb.append(element); 27 | sb.append(ZsonUtils.jsonStringEnd); 28 | } else { 29 | sb.append(element); 30 | } 31 | index++; 32 | } 33 | } 34 | sb.append(ZsonUtils.jsonListEnd); 35 | return sb.toString(); 36 | } 37 | 38 | public String toJsonString(Object obj) { 39 | ZsonObject objR = new ZsonObject(); 40 | objR.objectConvert(obj); 41 | if (objR.isMap()) { 42 | return this.mapToString(objR.getZsonMap()); 43 | } else if (objR.isList()) { 44 | return this.listToString(objR.getZsonList()); 45 | } else { 46 | throw new ZsonException("obj must be map or list!"); 47 | } 48 | } 49 | 50 | private String mapToString(Map map) { 51 | StringBuffer sb = new StringBuffer(); 52 | sb.append(ZsonUtils.jsonMapBegin); 53 | int index = 0; 54 | if (map != null) { 55 | for (Object key : map.keySet()) { 56 | if (index != 0) { 57 | sb.append(ZsonUtils.jsonElementConnector); 58 | } 59 | sb.append(ZsonUtils.jsonStringBegin); 60 | sb.append(key); 61 | sb.append(ZsonUtils.jsonStringEnd); 62 | sb.append(ZsonUtils.jsonMapConnector); 63 | if (map.get(key) instanceof Map || map.get(key) instanceof List) { 64 | String mapString = this.toJsonString(map.get(key)); 65 | sb.append(mapString); 66 | } else if (map.get(key) instanceof String) { 67 | sb.append(ZsonUtils.jsonStringBegin); 68 | sb.append(map.get(key)); 69 | sb.append(ZsonUtils.jsonStringEnd); 70 | } else { 71 | sb.append(map.get(key)); 72 | } 73 | index++; 74 | } 75 | } 76 | sb.append(ZsonUtils.jsonMapEnd); 77 | return sb.toString(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/com/zf/test/Demo.java: -------------------------------------------------------------------------------- 1 | package com.zf.test; 2 | 3 | import com.zf.zson.ZSON; 4 | import com.zf.zson.result.ZsonResult; 5 | 6 | public class Demo { 7 | 8 | public static void main(String[] args) { 9 | String s1 = "[{ \"firstName\": \"Eric\", \"lastName\": \"Clapton\", \"instrument\": \"guitar\" },{ \"firstName\": \"Sergei\", \"lastName\": \"Rachmaninoff\", \"instrument\": \"piano\" }] "; 10 | ZsonResult zr1 = ZSON.parseJson(s1); 11 | System.out.println(zr1.validateJsonClassTypes("[{\"firstName\":\"\",\"lastName\":\"\",\"instrument\":\"\"}]")); 12 | System.out.println(zr1.getPaths()); 13 | System.out.println(zr1.getClassTypes()); 14 | System.out.println(zr1.getValue("/*[1]/lastName")); 15 | System.out.println(zr1.getValues("/*[1]/lastName")); 16 | String s2 = "[0,1,2,3.14,4.00,\"3\",true,\"\"]"; 17 | System.out.println(ZSON.parseJson(s2).getBoolean("//*[6]")); 18 | 19 | ZsonResult zr2 = ZSON.parseJson(s2); 20 | System.out.println(zr2.getInteger("/*[1]")); 21 | System.out.println(zr2.getLong("/*[2]")); 22 | System.out.println(zr2.getDouble("/*[3]")); 23 | System.out.println(zr2.getFloat("/*[4]")); 24 | System.out.println(zr2.getString("/*[5]")); 25 | System.out.println(zr2.getBoolean("/*[6]")); 26 | String s3 = "{\"a\":[\"a1\",{\"a2\":123},\"a1\"],\"cb\":{\"a\":1},\"d\":[\"a\",{\"a\":[1,20,{\"a\":[90]}]},{\"a\":2},\"\"],\"e\":\"b\"}"; 27 | 28 | 29 | ZsonResult zr3 = ZSON.parseJson(s3); 30 | System.out.println(zr3.getValues("//*[0]")); 31 | System.out.println(zr3.getPaths()); 32 | System.out.println(zr3.getClassTypes()); 33 | zr3.addValue("//a/*[1]", "new"); 34 | zr3.addValue("/new", "{\"a\":12}"); 35 | System.out.println(zr3.getValues("//new")); 36 | System.out.println(zr3.getValue("")); 37 | zr3.deleteValue("//a2"); 38 | zr3.updateValue("//a", 3); 39 | System.out.println(zr3.getValue()); 40 | 41 | } 42 | 43 | } 44 | --------------------------------------------------------------------------------