PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/xiejuntao/xdesktop
Java | 343 lines | 281 code | 62 blank | 0 comment | 96 complexity | ce277d7868d885f24b7c657d232d6a52 MD5 | raw file
  1. package com.alibaba.fastjson.parser.deserializer;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Proxy;
  4. import java.lang.reflect.Type;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.IdentityHashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. import com.alibaba.fastjson.JSONException;
  11. import com.alibaba.fastjson.JSONObject;
  12. import com.alibaba.fastjson.parser.DefaultJSONParser;
  13. import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;
  14. import com.alibaba.fastjson.parser.Feature;
  15. import com.alibaba.fastjson.parser.JSONScanner;
  16. import com.alibaba.fastjson.parser.JSONToken;
  17. import com.alibaba.fastjson.parser.ParseContext;
  18. import com.alibaba.fastjson.parser.ParserConfig;
  19. import com.alibaba.fastjson.util.DeserializeBeanInfo;
  20. import com.alibaba.fastjson.util.FieldInfo;
  21. import com.alibaba.fastjson.util.TypeUtils;
  22. public class JavaBeanDeserializer implements ObjectDeserializer {
  23. private final Map<String, FieldDeserializer> feildDeserializerMap = new IdentityHashMap<String, FieldDeserializer>();
  24. private final List<FieldDeserializer> fieldDeserializers = new ArrayList<FieldDeserializer>();
  25. private final Class<?> clazz;
  26. private final Type type;
  27. private DeserializeBeanInfo beanInfo;
  28. public JavaBeanDeserializer(DeserializeBeanInfo beanInfo){
  29. this.beanInfo = beanInfo;
  30. this.clazz = beanInfo.getClazz();
  31. this.type = beanInfo.getType();
  32. }
  33. public JavaBeanDeserializer(ParserConfig config, Class<?> clazz){
  34. this(config, clazz, clazz);
  35. }
  36. public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){
  37. this.clazz = clazz;
  38. this.type = type;
  39. beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);
  40. for (FieldInfo fieldInfo : beanInfo.getFieldList()) {
  41. addFieldDeserializer(config, clazz, fieldInfo);
  42. }
  43. }
  44. public Map<String, FieldDeserializer> getFieldDeserializerMap() {
  45. return feildDeserializerMap;
  46. }
  47. public Class<?> getClazz() {
  48. return clazz;
  49. }
  50. public Type getType() {
  51. return type;
  52. }
  53. private void addFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
  54. FieldDeserializer fieldDeserializer = createFieldDeserializer(mapping, clazz, fieldInfo);
  55. feildDeserializerMap.put(fieldInfo.getName().intern(), fieldDeserializer);
  56. fieldDeserializers.add(fieldDeserializer);
  57. }
  58. public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
  59. return mapping.createFieldDeserializer(mapping, clazz, fieldInfo);
  60. }
  61. public Object createInstance(DefaultJSONParser parser, Type type) {
  62. if (type instanceof Class) {
  63. if (clazz.isInterface()) {
  64. Class<?> clazz = (Class<?>) type;
  65. ClassLoader loader = Thread.currentThread().getContextClassLoader();
  66. final JSONObject obj = new JSONObject();
  67. Object proxy = Proxy.newProxyInstance(loader, new Class<?>[] { clazz }, obj);
  68. return proxy;
  69. }
  70. }
  71. if (beanInfo.getDefaultConstructor() == null) {
  72. return null;
  73. }
  74. Object object;
  75. try {
  76. Constructor<?> constructor = beanInfo.getDefaultConstructor();
  77. if (constructor.getParameterTypes().length == 0) {
  78. object = constructor.newInstance();
  79. } else {
  80. object = constructor.newInstance(parser.getContext().getObject());
  81. }
  82. } catch (Exception e) {
  83. throw new JSONException("create instance error, class " + clazz.getName(), e);
  84. }
  85. if (parser.isEnabled(Feature.InitStringFieldAsEmpty)) {
  86. for (FieldInfo fieldInfo : beanInfo.getFieldList()) {
  87. if (fieldInfo.getFieldClass() == String.class) {
  88. try {
  89. fieldInfo.set(object, "");
  90. } catch (Exception e) {
  91. throw new JSONException("create instance error, class " + clazz.getName(), e);
  92. }
  93. }
  94. }
  95. }
  96. return object;
  97. }
  98. @SuppressWarnings("unchecked")
  99. public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
  100. JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx
  101. if (lexer.token() == JSONToken.NULL) {
  102. lexer.nextToken(JSONToken.COMMA);
  103. return null;
  104. }
  105. ParseContext context = parser.getContext();
  106. ParseContext childContext = null;
  107. Object object = null;
  108. try {
  109. Map<String, Object> fieldValues = null;
  110. if (lexer.token() == JSONToken.RBRACE) {
  111. lexer.nextToken(JSONToken.COMMA);
  112. return (T) createInstance(parser, type);
  113. }
  114. if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
  115. throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
  116. }
  117. if (parser.getResolveStatus() == DefaultJSONParser.TypeNameRedirect) {
  118. parser.setResolveStatus(DefaultJSONParser.NONE);
  119. }
  120. for (;;) {
  121. String key = lexer.scanSymbol(parser.getSymbolTable());
  122. if (key == null) {
  123. if (lexer.token() == JSONToken.RBRACE) {
  124. lexer.nextToken(JSONToken.COMMA);
  125. break;
  126. }
  127. if (lexer.token() == JSONToken.COMMA) {
  128. if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
  129. continue;
  130. }
  131. }
  132. }
  133. if ("$ref" == key) {
  134. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  135. if (lexer.token() == JSONToken.LITERAL_STRING) {
  136. String ref = lexer.stringVal();
  137. if ("@".equals(ref)) {
  138. object = context.getObject();
  139. } else if ("..".equals(ref)) {
  140. ParseContext parentContext = context.getParentContext();
  141. if (parentContext.getObject() != null) {
  142. object = parentContext.getObject();
  143. } else {
  144. parser.addResolveTask(new ResolveTask(parentContext, ref));
  145. parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
  146. }
  147. } else if ("$".equals(ref)) {
  148. ParseContext rootContext = context;
  149. while (rootContext.getParentContext() != null) {
  150. rootContext = rootContext.getParentContext();
  151. }
  152. if (rootContext.getObject() != null) {
  153. object = rootContext.getObject();
  154. } else {
  155. parser.addResolveTask(new ResolveTask(rootContext, ref));
  156. parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
  157. }
  158. } else {
  159. parser.addResolveTask(new ResolveTask(context, ref));
  160. parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
  161. }
  162. } else {
  163. throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
  164. }
  165. lexer.nextToken(JSONToken.RBRACE);
  166. if (lexer.token() != JSONToken.RBRACE) {
  167. throw new JSONException("illegal ref");
  168. }
  169. lexer.nextToken(JSONToken.COMMA);
  170. childContext = parser.setContext(context, object, fieldName);
  171. return (T) object;
  172. }
  173. if ("@type" == key) {
  174. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  175. if (lexer.token() == JSONToken.LITERAL_STRING) {
  176. String typeName = lexer.stringVal();
  177. lexer.nextToken(JSONToken.COMMA);
  178. if (type instanceof Class && typeName.equals(((Class<?>) type).getName())) {
  179. if (lexer.token() == JSONToken.RBRACE) {
  180. lexer.nextToken();
  181. break;
  182. }
  183. continue;
  184. }
  185. Class<?> userType = TypeUtils.loadClass(typeName);
  186. ObjectDeserializer deserizer = parser.getConfig().getDeserializer(userType);
  187. return (T) deserizer.deserialze(parser, userType, fieldName);
  188. } else {
  189. throw new JSONException("syntax error");
  190. }
  191. }
  192. if (object == null && fieldValues == null) {
  193. object = createInstance(parser, type);
  194. if (object == null) {
  195. fieldValues = new HashMap<String, Object>(this.fieldDeserializers.size());
  196. }
  197. childContext = parser.setContext(context, object, fieldName);
  198. }
  199. boolean match = parseField(parser, key, object, type, fieldValues);
  200. if (!match) {
  201. if (lexer.token() == JSONToken.RBRACE) {
  202. lexer.nextToken();
  203. break;
  204. }
  205. continue;
  206. }
  207. if (lexer.token() == JSONToken.COMMA) {
  208. continue;
  209. }
  210. if (lexer.token() == JSONToken.RBRACE) {
  211. lexer.nextToken(JSONToken.COMMA);
  212. break;
  213. }
  214. if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) {
  215. throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token()));
  216. }
  217. }
  218. if (object == null) {
  219. if (fieldValues == null) {
  220. object = createInstance(parser, type);
  221. return (T) object;
  222. }
  223. List<FieldInfo> fieldInfoList = beanInfo.getFieldList();
  224. int size = fieldInfoList.size();
  225. Object[] params = new Object[size];
  226. for (int i = 0; i < size; ++i) {
  227. FieldInfo fieldInfo = fieldInfoList.get(i);
  228. params[i] = fieldValues.get(fieldInfo.getName());
  229. }
  230. if (beanInfo.getCreatorConstructor() != null) {
  231. try {
  232. object = beanInfo.getCreatorConstructor().newInstance(params);
  233. } catch (Exception e) {
  234. throw new JSONException("create instance error, "
  235. + beanInfo.getCreatorConstructor().toGenericString(), e);
  236. }
  237. } else if (beanInfo.getFactoryMethod() != null) {
  238. try {
  239. object = beanInfo.getFactoryMethod().invoke(null, params);
  240. } catch (Exception e) {
  241. throw new JSONException("create factory method error, "
  242. + beanInfo.getFactoryMethod().toString(), e);
  243. }
  244. }
  245. }
  246. return (T) object;
  247. } finally {
  248. if (childContext != null) {
  249. childContext.setObject(object);
  250. }
  251. parser.setContext(context);
  252. }
  253. }
  254. public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType,
  255. Map<String, Object> fieldValues) {
  256. JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx
  257. FieldDeserializer fieldDeserializer = feildDeserializerMap.get(key);
  258. if (fieldDeserializer == null) {
  259. for (Map.Entry<String, FieldDeserializer> entry : feildDeserializerMap.entrySet()) {
  260. if (entry.getKey().equalsIgnoreCase(key)) {
  261. fieldDeserializer = entry.getValue();
  262. break;
  263. }
  264. }
  265. }
  266. if (fieldDeserializer == null) {
  267. if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
  268. throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
  269. }
  270. lexer.nextTokenWithColon();
  271. parser.parse(); // skip
  272. return false;
  273. }
  274. lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken());
  275. fieldDeserializer.parseField(parser, object, objectType, fieldValues);
  276. return true;
  277. }
  278. public int getFastMatchToken() {
  279. return JSONToken.LBRACE;
  280. }
  281. }