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

https://github.com/flydream/fastjson · Java · 356 lines · 334 code · 22 blank · 0 comment · 34 complexity · 2f2a94d342470af4e05424d53ba0f7b2 MD5 · raw file

  1. package com.alibaba.fastjson.parser.deserializer;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Modifier;
  4. import java.lang.reflect.ParameterizedType;
  5. import java.lang.reflect.Type;
  6. import java.lang.reflect.TypeVariable;
  7. import java.lang.reflect.WildcardType;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.Properties;
  12. import java.util.SortedMap;
  13. import java.util.TreeMap;
  14. import java.util.concurrent.ConcurrentHashMap;
  15. import java.util.concurrent.ConcurrentMap;
  16. import com.alibaba.fastjson.JSONException;
  17. import com.alibaba.fastjson.parser.DefaultJSONParser;
  18. import com.alibaba.fastjson.parser.Feature;
  19. import com.alibaba.fastjson.parser.JSONScanner;
  20. import com.alibaba.fastjson.parser.JSONToken;
  21. import com.alibaba.fastjson.util.ASMClassLoader;
  22. import com.alibaba.fastjson.util.TypeUtils;
  23. public class DefaultObjectDeserializer implements ObjectDeserializer {
  24. public DefaultObjectDeserializer(){
  25. }
  26. public void parseMap(DefaultJSONParser parser, Map<Object, Object> map, Type keyType, Type valueType, Object fieldName) {
  27. JSONScanner lexer = (JSONScanner) parser.getLexer();
  28. if (lexer.token() != JSONToken.LBRACE) {
  29. throw new JSONException("syntax error, expect {, actual " + lexer.token());
  30. }
  31. ObjectDeserializer keyDeserializer = parser.getConfig().getDeserializer(keyType);
  32. ObjectDeserializer valueDeserializer = parser.getConfig().getDeserializer(valueType);
  33. lexer.nextToken(keyDeserializer.getFastMatchToken());
  34. for (;;) {
  35. if (lexer.token() == JSONToken.RBRACE) {
  36. lexer.nextToken(JSONToken.COMMA);
  37. break;
  38. }
  39. Object key = keyDeserializer.deserialze(parser, keyType, null);
  40. if (lexer.token() != JSONToken.COLON) {
  41. throw new JSONException("syntax error, expect :, actual " + lexer.token());
  42. }
  43. lexer.nextToken(valueDeserializer.getFastMatchToken());
  44. Object value = valueDeserializer.deserialze(parser, valueType, key);
  45. map.put(key, value);
  46. if (lexer.token() == JSONToken.COMMA) {
  47. lexer.nextToken(keyDeserializer.getFastMatchToken());
  48. }
  49. }
  50. }
  51. @SuppressWarnings("rawtypes")
  52. public Map parseMap(DefaultJSONParser parser, Map<String, Object> map, Type valueType, Object fieldName) {
  53. JSONScanner lexer = (JSONScanner) parser.getLexer();
  54. if (lexer.token() != JSONToken.LBRACE) {
  55. throw new JSONException("syntax error, expect {, actual " + lexer.token());
  56. }
  57. for (;;) {
  58. lexer.skipWhitespace();
  59. char ch = lexer.getCurrent();
  60. if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
  61. while (ch == ',') {
  62. lexer.incrementBufferPosition();
  63. lexer.skipWhitespace();
  64. ch = lexer.getCurrent();
  65. }
  66. }
  67. String key;
  68. if (ch == '"') {
  69. key = lexer.scanSymbol(parser.getSymbolTable(), '"');
  70. lexer.skipWhitespace();
  71. ch = lexer.getCurrent();
  72. if (ch != ':') {
  73. throw new JSONException("expect ':' at " + lexer.pos());
  74. }
  75. } else if (ch == '}') {
  76. lexer.incrementBufferPosition();
  77. lexer.resetStringPosition();
  78. return map;
  79. } else if (ch == '\'') {
  80. if (!parser.isEnabled(Feature.AllowSingleQuotes)) {
  81. throw new JSONException("syntax error");
  82. }
  83. key = lexer.scanSymbol(parser.getSymbolTable(), '\'');
  84. lexer.skipWhitespace();
  85. ch = lexer.getCurrent();
  86. if (ch != ':') {
  87. throw new JSONException("expect ':' at " + lexer.pos());
  88. }
  89. } else {
  90. if (!parser.isEnabled(Feature.AllowUnQuotedFieldNames)) {
  91. throw new JSONException("syntax error");
  92. }
  93. key = lexer.scanSymbolUnQuoted(parser.getSymbolTable());
  94. lexer.skipWhitespace();
  95. ch = lexer.getCurrent();
  96. if (ch != ':') {
  97. throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
  98. }
  99. }
  100. lexer.incrementBufferPosition();
  101. lexer.skipWhitespace();
  102. ch = lexer.getCurrent();
  103. lexer.resetStringPosition();
  104. if (key == "@type") {
  105. String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"');
  106. Class<?> clazz = TypeUtils.loadClass(typeName);
  107. if (clazz == map.getClass()) {
  108. lexer.nextToken(JSONToken.COMMA);
  109. continue;
  110. }
  111. ObjectDeserializer deserializer = parser.getConfig().getDeserializer(clazz);
  112. lexer.nextToken(JSONToken.COMMA);
  113. parser.setResolveStatus(DefaultJSONParser.TypeNameRedirect);
  114. return (Map) deserializer.deserialze(parser, clazz, fieldName);
  115. }
  116. Object value;
  117. lexer.nextToken();
  118. if (lexer.token() == JSONToken.NULL) {
  119. value = null;
  120. lexer.nextToken();
  121. } else {
  122. value = parser.parseObject(valueType);
  123. }
  124. map.put(key, value);
  125. if (lexer.token() == JSONToken.RBRACE) {
  126. lexer.nextToken();
  127. return map;
  128. }
  129. }
  130. }
  131. public void parseObject(DefaultJSONParser parser, Object object) {
  132. Class<?> clazz = object.getClass();
  133. Map<String, FieldDeserializer> setters = parser.getConfig().getFieldDeserializers(clazz);
  134. JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx
  135. if (lexer.token() != JSONToken.LBRACE) {
  136. throw new JSONException("syntax error, expect {, actual " + lexer.token());
  137. }
  138. final Object[] args = new Object[1];
  139. for (;;) {
  140. // lexer.scanSymbol
  141. String key = lexer.scanSymbol(parser.getSymbolTable());
  142. if (key == null) {
  143. if (lexer.token() == JSONToken.RBRACE) {
  144. lexer.nextToken(JSONToken.COMMA);
  145. break;
  146. }
  147. if (lexer.token() == JSONToken.COMMA) {
  148. if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
  149. continue;
  150. }
  151. }
  152. }
  153. FieldDeserializer fieldDeser = setters.get(key);
  154. if (fieldDeser == null) {
  155. if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
  156. throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
  157. }
  158. lexer.nextTokenWithColon();
  159. parser.parse(); // skip
  160. if (lexer.token() == JSONToken.RBRACE) {
  161. lexer.nextToken();
  162. return;
  163. }
  164. continue;
  165. } else {
  166. Method method = fieldDeser.getMethod();
  167. Class<?> fieldClass = method.getParameterTypes()[0];
  168. Type fieldType = method.getGenericParameterTypes()[0];
  169. if (fieldClass == int.class) {
  170. lexer.nextTokenWithColon(JSONToken.LITERAL_INT);
  171. args[0] = IntegerDeserializer.deserialze(parser);
  172. } else if (fieldClass == String.class) {
  173. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  174. args[0] = StringDeserializer.deserialze(parser);
  175. } else if (fieldClass == long.class) {
  176. lexer.nextTokenWithColon(JSONToken.LITERAL_INT);
  177. args[0] = LongDeserializer.deserialze(parser);
  178. } else if (fieldClass == List.class) {
  179. lexer.nextTokenWithColon(JSONToken.LBRACE);
  180. args[0] = CollectionDeserializer.instance.deserialze(parser, fieldType, null);
  181. } else {
  182. ObjectDeserializer fieldValueDeserializer = parser.getConfig().getDeserializer(fieldClass,
  183. fieldType);
  184. lexer.nextTokenWithColon(fieldValueDeserializer.getFastMatchToken());
  185. args[0] = fieldValueDeserializer.deserialze(parser, fieldType, null);
  186. }
  187. try {
  188. method.invoke(object, args);
  189. } catch (Exception e) {
  190. throw new JSONException("set proprety error, " + method.getName(), e);
  191. }
  192. }
  193. if (lexer.token() == JSONToken.COMMA) {
  194. continue;
  195. }
  196. if (lexer.token() == JSONToken.RBRACE) {
  197. lexer.nextToken(JSONToken.COMMA);
  198. return;
  199. }
  200. }
  201. }
  202. @SuppressWarnings("unchecked")
  203. public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
  204. if (type instanceof Class<?>) {
  205. return deserialze(parser, (Class<T>) type);
  206. }
  207. if (type instanceof ParameterizedType) {
  208. return (T) deserialze(parser, (ParameterizedType) type, fieldName);
  209. }
  210. if (type instanceof TypeVariable) {
  211. return (T) parser.parse(fieldName);
  212. }
  213. if (type instanceof WildcardType) {
  214. return (T) parser.parse(fieldName);
  215. }
  216. throw new JSONException("not support type : " + type);
  217. }
  218. @SuppressWarnings({ "rawtypes", "unchecked" })
  219. public <T> T deserialze(DefaultJSONParser parser, ParameterizedType type, Object fieldName) {
  220. try {
  221. Type rawType = type.getRawType();
  222. if (rawType instanceof Class<?>) {
  223. Class<?> rawClass = (Class<?>) rawType;
  224. if (Map.class.isAssignableFrom(rawClass)) {
  225. Map map;
  226. if (Modifier.isAbstract(rawClass.getModifiers())) {
  227. if (rawClass == Map.class) {
  228. map = new HashMap();
  229. } else if (rawClass == SortedMap.class) {
  230. map = new TreeMap();
  231. } else if (rawClass == ConcurrentMap.class) {
  232. map = new ConcurrentHashMap();
  233. } else {
  234. throw new JSONException("can not create instance : " + rawClass);
  235. }
  236. } else {
  237. if (rawClass == HashMap.class) {
  238. map = new HashMap();
  239. } else {
  240. map = (Map) rawClass.newInstance();
  241. }
  242. }
  243. Type keyType = type.getActualTypeArguments()[0];
  244. Type valueType = type.getActualTypeArguments()[1];
  245. if (keyType == String.class) {
  246. map = parseMap(parser, map, valueType, fieldName);
  247. } else {
  248. parseMap(parser, map, keyType, valueType, fieldName);
  249. }
  250. return (T) map;
  251. }
  252. }
  253. throw new JSONException("not support type : " + type);
  254. } catch (JSONException e) {
  255. throw e;
  256. } catch (Throwable e) {
  257. throw new JSONException(e.getMessage(), e);
  258. }
  259. }
  260. @SuppressWarnings({ "rawtypes", "unchecked" })
  261. public <T> T deserialze(DefaultJSONParser parser, Class<T> clazz) {
  262. Object value = null;
  263. if (clazz.isAssignableFrom(HashMap.class)) {
  264. value = new HashMap();
  265. } else if (clazz.isAssignableFrom(TreeMap.class)) {
  266. value = new TreeMap();
  267. } else if (clazz.isAssignableFrom(ConcurrentHashMap.class)) {
  268. value = new ConcurrentHashMap();
  269. } else if (clazz.isAssignableFrom(Properties.class)) {
  270. value = new Properties();
  271. }
  272. if (clazz == Class.class) {
  273. Object classValue = parser.parse();
  274. if (classValue == null) {
  275. return null;
  276. }
  277. if (classValue instanceof String) {
  278. return (T) ASMClassLoader.forName((String) classValue);
  279. }
  280. }
  281. try {
  282. parseObject(parser, value);
  283. return (T) value;
  284. } catch (JSONException e) {
  285. throw e;
  286. } catch (Throwable e) {
  287. throw new JSONException(e.getMessage(), e);
  288. }
  289. }
  290. public int getFastMatchToken() {
  291. return JSONToken.LBRACE;
  292. }
  293. }