PageRenderTime 64ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 487 lines | 452 code | 33 blank | 2 comment | 69 complexity | b9a8dd5505b0c922fec20639f0d15b3f MD5 | raw file
  1. package com.alibaba.fastjson.parser.deserializer;
  2. import java.io.Serializable;
  3. import java.lang.reflect.Array;
  4. import java.lang.reflect.GenericArrayType;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.Modifier;
  7. import java.lang.reflect.ParameterizedType;
  8. import java.lang.reflect.Type;
  9. import java.lang.reflect.TypeVariable;
  10. import java.lang.reflect.WildcardType;
  11. import java.util.ArrayList;
  12. import java.util.HashMap;
  13. import java.util.IdentityHashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. import java.util.Properties;
  17. import java.util.SortedMap;
  18. import java.util.TreeMap;
  19. import java.util.concurrent.ConcurrentHashMap;
  20. import java.util.concurrent.ConcurrentMap;
  21. import com.alibaba.fastjson.JSONException;
  22. import com.alibaba.fastjson.parser.DefaultJSONParser;
  23. import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;
  24. import com.alibaba.fastjson.parser.Feature;
  25. import com.alibaba.fastjson.parser.JSONLexer;
  26. import com.alibaba.fastjson.parser.JSONScanner;
  27. import com.alibaba.fastjson.parser.JSONToken;
  28. import com.alibaba.fastjson.parser.ParseContext;
  29. import com.alibaba.fastjson.util.ASMClassLoader;
  30. import com.alibaba.fastjson.util.TypeUtils;
  31. public class DefaultObjectDeserializer implements ObjectDeserializer {
  32. public final static DefaultObjectDeserializer instance = new DefaultObjectDeserializer();
  33. public DefaultObjectDeserializer(){
  34. }
  35. public Object parseMap(DefaultJSONParser parser, Map<Object, Object> map, Type keyType, Type valueType,
  36. Object fieldName) {
  37. JSONScanner lexer = (JSONScanner) parser.getLexer();
  38. if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
  39. throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
  40. }
  41. ObjectDeserializer keyDeserializer = parser.getConfig().getDeserializer(keyType);
  42. ObjectDeserializer valueDeserializer = parser.getConfig().getDeserializer(valueType);
  43. lexer.nextToken(keyDeserializer.getFastMatchToken());
  44. ParseContext context = parser.getContext();
  45. try {
  46. for (;;) {
  47. if (lexer.token() == JSONToken.RBRACE) {
  48. lexer.nextToken(JSONToken.COMMA);
  49. break;
  50. }
  51. if (lexer.token() == JSONToken.LITERAL_STRING && lexer.isRef()) {
  52. Object object = null;
  53. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  54. if (lexer.token() == JSONToken.LITERAL_STRING) {
  55. String ref = lexer.stringVal();
  56. if ("@".equals(ref)) {
  57. object = context.getObject();
  58. } else if ("..".equals(ref)) {
  59. ParseContext parentContext = context.getParentContext();
  60. if (parentContext.getObject() != null) {
  61. object = parentContext.getObject();
  62. } else {
  63. parser.addResolveTask(new ResolveTask(parentContext, ref));
  64. parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
  65. }
  66. } else if ("$".equals(ref)) {
  67. ParseContext rootContext = context;
  68. while (rootContext.getParentContext() != null) {
  69. rootContext = rootContext.getParentContext();
  70. }
  71. if (rootContext.getObject() != null) {
  72. object = rootContext.getObject();
  73. } else {
  74. parser.addResolveTask(new ResolveTask(rootContext, ref));
  75. parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
  76. }
  77. } else {
  78. parser.addResolveTask(new ResolveTask(context, ref));
  79. parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
  80. }
  81. } else {
  82. throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
  83. }
  84. lexer.nextToken(JSONToken.RBRACE);
  85. if (lexer.token() != JSONToken.RBRACE) {
  86. throw new JSONException("illegal ref");
  87. }
  88. lexer.nextToken(JSONToken.COMMA);
  89. //parser.setContext(context, map, fieldName);
  90. //parser.setContext(context);
  91. return object;
  92. }
  93. if (map.size() == 0 && lexer.token() == JSONToken.LITERAL_STRING && "@type".equals(lexer.stringVal())) {
  94. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  95. lexer.nextToken(JSONToken.COMMA);
  96. lexer.nextToken(keyDeserializer.getFastMatchToken());
  97. }
  98. Object key = keyDeserializer.deserialze(parser, keyType, null);
  99. if (lexer.token() != JSONToken.COLON) {
  100. throw new JSONException("syntax error, expect :, actual " + lexer.token());
  101. }
  102. lexer.nextToken(valueDeserializer.getFastMatchToken());
  103. Object value = valueDeserializer.deserialze(parser, valueType, key);
  104. if (map.size() == 0 && context != null && context.getObject() != map) {
  105. parser.setContext(context, map, fieldName);
  106. }
  107. map.put(key, value);
  108. if (lexer.token() == JSONToken.COMMA) {
  109. lexer.nextToken(keyDeserializer.getFastMatchToken());
  110. }
  111. }
  112. } finally {
  113. parser.setContext(context);
  114. }
  115. return map;
  116. }
  117. @SuppressWarnings("rawtypes")
  118. public Map parseMap(DefaultJSONParser parser, Map<String, Object> map, Type valueType, Object fieldName) {
  119. JSONScanner lexer = (JSONScanner) parser.getLexer();
  120. if (lexer.token() != JSONToken.LBRACE) {
  121. throw new JSONException("syntax error, expect {, actual " + lexer.token());
  122. }
  123. ParseContext context = parser.getContext();
  124. try {
  125. for (;;) {
  126. lexer.skipWhitespace();
  127. char ch = lexer.getCurrent();
  128. if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
  129. while (ch == ',') {
  130. lexer.incrementBufferPosition();
  131. lexer.skipWhitespace();
  132. ch = lexer.getCurrent();
  133. }
  134. }
  135. String key;
  136. if (ch == '"') {
  137. key = lexer.scanSymbol(parser.getSymbolTable(), '"');
  138. lexer.skipWhitespace();
  139. ch = lexer.getCurrent();
  140. if (ch != ':') {
  141. throw new JSONException("expect ':' at " + lexer.pos());
  142. }
  143. } else if (ch == '}') {
  144. lexer.incrementBufferPosition();
  145. lexer.resetStringPosition();
  146. lexer.nextToken(JSONToken.COMMA);
  147. return map;
  148. } else if (ch == '\'') {
  149. if (!parser.isEnabled(Feature.AllowSingleQuotes)) {
  150. throw new JSONException("syntax error");
  151. }
  152. key = lexer.scanSymbol(parser.getSymbolTable(), '\'');
  153. lexer.skipWhitespace();
  154. ch = lexer.getCurrent();
  155. if (ch != ':') {
  156. throw new JSONException("expect ':' at " + lexer.pos());
  157. }
  158. } else {
  159. if (!parser.isEnabled(Feature.AllowUnQuotedFieldNames)) {
  160. throw new JSONException("syntax error");
  161. }
  162. key = lexer.scanSymbolUnQuoted(parser.getSymbolTable());
  163. lexer.skipWhitespace();
  164. ch = lexer.getCurrent();
  165. if (ch != ':') {
  166. throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
  167. }
  168. }
  169. lexer.incrementBufferPosition();
  170. lexer.skipWhitespace();
  171. ch = lexer.getCurrent();
  172. lexer.resetStringPosition();
  173. if (key == "@type") {
  174. String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"');
  175. Class<?> clazz = TypeUtils.loadClass(typeName);
  176. if (clazz == map.getClass()) {
  177. lexer.nextToken(JSONToken.COMMA);
  178. if (lexer.token() == JSONToken.RBRACE) {
  179. lexer.nextToken(JSONToken.COMMA);
  180. return map;
  181. }
  182. continue;
  183. }
  184. ObjectDeserializer deserializer = parser.getConfig().getDeserializer(clazz);
  185. lexer.nextToken(JSONToken.COMMA);
  186. parser.setResolveStatus(DefaultJSONParser.TypeNameRedirect);
  187. if (context != null && !(fieldName instanceof Integer)) {
  188. parser.popContext();
  189. }
  190. return (Map) deserializer.deserialze(parser, clazz, fieldName);
  191. }
  192. Object value;
  193. lexer.nextToken();
  194. if (lexer.token() == JSONToken.NULL) {
  195. value = null;
  196. lexer.nextToken();
  197. } else {
  198. value = parser.parseObject(valueType);
  199. }
  200. map.put(key, value);
  201. parser.checkMapResolve(map, key);
  202. parser.setContext(context, value, key);
  203. if (lexer.token() == JSONToken.RBRACE) {
  204. lexer.nextToken();
  205. return map;
  206. }
  207. }
  208. } finally {
  209. parser.setContext(context);
  210. }
  211. }
  212. public void parseObject(DefaultJSONParser parser, Object object) {
  213. Class<?> clazz = object.getClass();
  214. Map<String, FieldDeserializer> setters = parser.getConfig().getFieldDeserializers(clazz);
  215. JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx
  216. if (lexer.token() == JSONToken.RBRACE) {
  217. lexer.nextToken(JSONToken.COMMA);
  218. return;
  219. }
  220. if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
  221. throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
  222. }
  223. final Object[] args = new Object[1];
  224. for (;;) {
  225. // lexer.scanSymbol
  226. String key = lexer.scanSymbol(parser.getSymbolTable());
  227. if (key == null) {
  228. if (lexer.token() == JSONToken.RBRACE) {
  229. lexer.nextToken(JSONToken.COMMA);
  230. break;
  231. }
  232. if (lexer.token() == JSONToken.COMMA) {
  233. if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
  234. continue;
  235. }
  236. }
  237. }
  238. FieldDeserializer fieldDeser = setters.get(key);
  239. if (fieldDeser == null) {
  240. if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
  241. throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
  242. }
  243. lexer.nextTokenWithColon();
  244. parser.parse(); // skip
  245. if (lexer.token() == JSONToken.RBRACE) {
  246. lexer.nextToken();
  247. return;
  248. }
  249. continue;
  250. } else {
  251. Method method = fieldDeser.getMethod();
  252. Class<?> fieldClass = method.getParameterTypes()[0];
  253. Type fieldType = method.getGenericParameterTypes()[0];
  254. if (fieldClass == int.class) {
  255. lexer.nextTokenWithColon(JSONToken.LITERAL_INT);
  256. args[0] = IntegerDeserializer.deserialze(parser);
  257. } else if (fieldClass == String.class) {
  258. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  259. args[0] = StringDeserializer.deserialze(parser);
  260. } else if (fieldClass == long.class) {
  261. lexer.nextTokenWithColon(JSONToken.LITERAL_INT);
  262. args[0] = LongDeserializer.deserialze(parser);
  263. } else if (fieldClass == List.class) {
  264. lexer.nextTokenWithColon(JSONToken.LBRACE);
  265. args[0] = CollectionDeserializer.instance.deserialze(parser, fieldType, null);
  266. } else {
  267. ObjectDeserializer fieldValueDeserializer = parser.getConfig().getDeserializer(fieldClass,
  268. fieldType);
  269. lexer.nextTokenWithColon(fieldValueDeserializer.getFastMatchToken());
  270. args[0] = fieldValueDeserializer.deserialze(parser, fieldType, null);
  271. }
  272. try {
  273. method.invoke(object, args);
  274. } catch (Exception e) {
  275. throw new JSONException("set proprety error, " + method.getName(), e);
  276. }
  277. }
  278. if (lexer.token() == JSONToken.COMMA) {
  279. continue;
  280. }
  281. if (lexer.token() == JSONToken.RBRACE) {
  282. lexer.nextToken(JSONToken.COMMA);
  283. return;
  284. }
  285. }
  286. }
  287. @SuppressWarnings("unchecked")
  288. public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
  289. if (type instanceof Class<?>) {
  290. return deserialze(parser, (Class<T>) type);
  291. }
  292. if (type instanceof ParameterizedType) {
  293. return (T) deserialze(parser, (ParameterizedType) type, fieldName);
  294. }
  295. if (type instanceof TypeVariable) {
  296. return (T) parser.parse(fieldName);
  297. }
  298. if (type instanceof WildcardType) {
  299. return (T) parser.parse(fieldName);
  300. }
  301. if (type instanceof GenericArrayType) {
  302. Type componentType = ((GenericArrayType) type).getGenericComponentType();
  303. List<Object> list = new ArrayList<Object>();
  304. parser.parseArray(componentType, list);
  305. if (componentType instanceof Class) {
  306. Class<?> componentClass = (Class<?>) componentType;
  307. Object[] array = (Object[]) Array.newInstance(componentClass, list.size());
  308. list.toArray(array);
  309. return (T) array;
  310. }
  311. }
  312. throw new JSONException("not support type : " + type);
  313. }
  314. @SuppressWarnings({ "rawtypes", "unchecked" })
  315. public <T> T deserialze(DefaultJSONParser parser, ParameterizedType type, Object fieldName) {
  316. try {
  317. JSONLexer lexer = parser.getLexer();
  318. if (lexer.token() == JSONToken.NULL) {
  319. lexer.nextToken();
  320. return null;
  321. }
  322. Type rawType = type.getRawType();
  323. if (rawType instanceof Class<?>) {
  324. Class<?> rawClass = (Class<?>) rawType;
  325. if (Map.class.isAssignableFrom(rawClass)) {
  326. Map map;
  327. if (Modifier.isAbstract(rawClass.getModifiers())) {
  328. if (rawClass == Map.class) {
  329. map = new HashMap();
  330. } else if (rawClass == SortedMap.class) {
  331. map = new TreeMap();
  332. } else if (rawClass == ConcurrentMap.class) {
  333. map = new ConcurrentHashMap();
  334. } else {
  335. throw new JSONException("can not create instance : " + rawClass);
  336. }
  337. } else {
  338. if (rawClass == HashMap.class) {
  339. map = new HashMap();
  340. } else {
  341. map = (Map) rawClass.newInstance();
  342. }
  343. }
  344. Type keyType = type.getActualTypeArguments()[0];
  345. Type valueType = type.getActualTypeArguments()[1];
  346. if (keyType == String.class) {
  347. return (T) parseMap(parser, map, valueType, fieldName);
  348. } else {
  349. return (T) parseMap(parser, map, keyType, valueType, fieldName);
  350. }
  351. }
  352. }
  353. throw new JSONException("not support type : " + type);
  354. } catch (JSONException e) {
  355. throw e;
  356. } catch (Throwable e) {
  357. throw new JSONException(e.getMessage(), e);
  358. }
  359. }
  360. @SuppressWarnings({ "rawtypes", "unchecked" })
  361. public <T> T deserialze(DefaultJSONParser parser, Class<T> clazz) {
  362. Object value = null;
  363. if (parser.getLexer().token() == JSONToken.NULL) {
  364. parser.getLexer().nextToken(JSONToken.COMMA);
  365. return null;
  366. }
  367. if (clazz.isAssignableFrom(HashMap.class)) {
  368. value = new HashMap();
  369. } else if (clazz.isAssignableFrom(TreeMap.class)) {
  370. value = new TreeMap();
  371. } else if (clazz.isAssignableFrom(ConcurrentHashMap.class)) {
  372. value = new ConcurrentHashMap();
  373. } else if (clazz.isAssignableFrom(Properties.class)) {
  374. value = new Properties();
  375. } else if (clazz.isAssignableFrom(IdentityHashMap.class)) {
  376. value = new IdentityHashMap();
  377. }
  378. if (clazz == Class.class) {
  379. Object classValue = parser.parse();
  380. if (classValue == null) {
  381. return null;
  382. }
  383. if (classValue instanceof String) {
  384. return (T) ASMClassLoader.forName((String) classValue);
  385. }
  386. } else if (clazz == Serializable.class) {
  387. return (T) parser.parse();
  388. }
  389. if (value == null) {
  390. throw new JSONException("not support type : " + clazz);
  391. }
  392. try {
  393. parseObject(parser, value);
  394. return (T) value;
  395. } catch (JSONException e) {
  396. throw e;
  397. } catch (Throwable e) {
  398. throw new JSONException(e.getMessage(), e);
  399. }
  400. }
  401. public int getFastMatchToken() {
  402. return JSONToken.LBRACE;
  403. }
  404. }