/sekiro-lib/src/main/java/external/com/alibaba/fastjson/parser/ListTypeFieldDeserializer.java

https://github.com/virjar/sekiro · Java · 255 lines · 227 code · 28 blank · 0 comment · 65 complexity · 4ef6df410c33cd3cf446647aec4bfed1 MD5 · raw file

  1. package external.com.alibaba.fastjson.parser;
  2. import java.lang.reflect.*;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.List;
  6. import java.util.Map;
  7. import external.com.alibaba.fastjson.JSONArray;
  8. import external.com.alibaba.fastjson.JSONException;
  9. import external.com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
  10. import external.com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
  11. import external.com.alibaba.fastjson.util.FieldInfo;
  12. import external.com.alibaba.fastjson.util.ParameterizedTypeImpl;
  13. import external.com.alibaba.fastjson.util.TypeUtils;
  14. class ListTypeFieldDeserializer extends FieldDeserializer {
  15. private final Type itemType;
  16. private ObjectDeserializer deserializer;
  17. private final boolean array;
  18. public ListTypeFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo){
  19. super(clazz, fieldInfo, JSONToken.LBRACKET);
  20. Type fieldType = fieldInfo.fieldType;
  21. Class<?> fieldClass= fieldInfo.fieldClass;
  22. if (fieldClass.isArray()) {
  23. this.itemType = fieldClass.getComponentType();
  24. array = true;
  25. } else {
  26. this.itemType = TypeUtils.getCollectionItemType(fieldType);
  27. array = false;
  28. }
  29. }
  30. @SuppressWarnings({ "rawtypes", "unchecked" })
  31. @Override
  32. public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) {
  33. JSONLexer lexer = parser.lexer;
  34. final int token = lexer.token();
  35. if (token == JSONToken.NULL
  36. || (token == JSONToken.LITERAL_STRING && lexer.stringVal().length() == 0)) {
  37. setValue(object, null);
  38. parser.lexer.nextToken();
  39. return;
  40. }
  41. JSONArray jsonArray = null;
  42. List list;
  43. if (array) {
  44. list = jsonArray = new JSONArray();
  45. jsonArray.setComponentType(itemType);
  46. } else {
  47. list = new ArrayList();
  48. }
  49. ParseContext context = parser.contex;
  50. parser.setContext(context, object, fieldInfo.name);
  51. parseArray(parser, objectType, list);
  52. parser.setContext(context);
  53. Object fieldValue;
  54. if (array) {
  55. Object[] arrayValue = (Object[]) Array.newInstance((Class<?>)itemType, list.size());
  56. fieldValue = list.toArray(arrayValue);
  57. jsonArray.setRelatedArray(fieldValue);
  58. } else {
  59. fieldValue = list;
  60. }
  61. if (object == null) {
  62. fieldValues.put(fieldInfo.name, fieldValue);
  63. } else {
  64. setValue(object, fieldValue);
  65. }
  66. }
  67. @SuppressWarnings({ "unchecked", "rawtypes" })
  68. final void parseArray(DefaultJSONParser parser, Type objectType, Collection array) {
  69. Type itemType = this.itemType;
  70. ObjectDeserializer itemTypeDeser = this.deserializer;
  71. if (objectType instanceof ParameterizedType) {
  72. if (itemType instanceof TypeVariable) {
  73. TypeVariable typeVar = (TypeVariable) itemType;
  74. ParameterizedType paramType = (ParameterizedType) objectType;
  75. Class<?> objectClass = null;
  76. if (paramType.getRawType() instanceof Class) {
  77. objectClass = (Class<?>) paramType.getRawType();
  78. }
  79. int paramIndex = -1;
  80. if (objectClass != null) {
  81. for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) {
  82. TypeVariable item = objectClass.getTypeParameters()[i];
  83. if (item.getName().equals(typeVar.getName())) {
  84. paramIndex = i;
  85. break;
  86. }
  87. }
  88. }
  89. if (paramIndex != -1) {
  90. itemType = paramType.getActualTypeArguments()[paramIndex];
  91. if (!itemType.equals(this.itemType)) {
  92. itemTypeDeser = parser.config.getDeserializer(itemType);
  93. }
  94. }
  95. } else if (itemType instanceof ParameterizedType) {
  96. ParameterizedType parameterizedItemType = (ParameterizedType) itemType;
  97. Type[] itemActualTypeArgs = parameterizedItemType.getActualTypeArguments();
  98. if (itemActualTypeArgs.length == 1 && itemActualTypeArgs[0] instanceof TypeVariable) {
  99. TypeVariable typeVar = (TypeVariable) itemActualTypeArgs[0];
  100. ParameterizedType paramType = (ParameterizedType) objectType;
  101. Class<?> objectClass = null;
  102. if (paramType.getRawType() instanceof Class) {
  103. objectClass = (Class<?>) paramType.getRawType();
  104. }
  105. int paramIndex = -1;
  106. if (objectClass != null) {
  107. for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) {
  108. TypeVariable item = objectClass.getTypeParameters()[i];
  109. if (item.getName().equals(typeVar.getName())) {
  110. paramIndex = i;
  111. break;
  112. }
  113. }
  114. }
  115. if (paramIndex != -1) {
  116. itemActualTypeArgs[0] = paramType.getActualTypeArguments()[paramIndex];
  117. itemType = new ParameterizedTypeImpl(itemActualTypeArgs, parameterizedItemType.getOwnerType(), parameterizedItemType.getRawType());
  118. }
  119. }
  120. }
  121. } else if (itemType instanceof TypeVariable && objectType instanceof Class) {
  122. Class objectClass = (Class) objectType;
  123. TypeVariable typeVar = (TypeVariable) itemType;
  124. objectClass.getTypeParameters();
  125. for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) {
  126. TypeVariable item = objectClass.getTypeParameters()[i];
  127. if (item.getName().equals(typeVar.getName())) {
  128. Type[] bounds = item.getBounds();
  129. if (bounds.length == 1) {
  130. itemType = bounds[0];
  131. }
  132. break;
  133. }
  134. }
  135. }
  136. final JSONLexer lexer = parser.lexer;
  137. if (itemTypeDeser == null) {
  138. itemTypeDeser = deserializer = parser.config.getDeserializer(itemType);
  139. }
  140. if (lexer.token != JSONToken.LBRACKET) {
  141. if (lexer.token == JSONToken.LBRACE) {
  142. Object val = itemTypeDeser.deserialze(parser, itemType, 0);
  143. array.add(val);
  144. return;
  145. } else {
  146. String errorMessage = "exepct '[', but " + JSONToken.name(lexer.token);
  147. if (objectType != null) {
  148. errorMessage += ", type : " + objectType;
  149. }
  150. throw new JSONException(errorMessage);
  151. }
  152. }
  153. int ch = lexer.ch;
  154. if (ch == '[') {
  155. int index = ++lexer.bp;
  156. lexer.ch = (index >= lexer.len ? //
  157. JSONLexer.EOI //
  158. : lexer.text.charAt(index));
  159. lexer.token = JSONToken.LBRACKET;
  160. } else if (ch == '{') {
  161. int index = ++lexer.bp;
  162. lexer.ch = (index >= lexer.len ? //
  163. JSONLexer.EOI //
  164. : lexer.text.charAt(index));
  165. lexer.token = JSONToken.LBRACE;
  166. } else if (ch == '"') {
  167. lexer.scanString();
  168. } else if (ch == ']') {
  169. int index = ++lexer.bp;
  170. lexer.ch = (index >= lexer.len ? //
  171. JSONLexer.EOI //
  172. : lexer.text.charAt(index));
  173. lexer.token = JSONToken.RBRACKET;
  174. } else {
  175. lexer.nextToken();
  176. }
  177. for (int i = 0;; ++i) {
  178. while (lexer.token == JSONToken.COMMA) {
  179. lexer.nextToken();
  180. continue;
  181. }
  182. if (lexer.token == JSONToken.RBRACKET) {
  183. break;
  184. }
  185. Object val = itemTypeDeser.deserialze(parser, itemType, i);
  186. array.add(val);
  187. if (parser.resolveStatus == DefaultJSONParser.NeedToResolve) {
  188. parser.checkListResolve(array);
  189. }
  190. if (lexer.token == JSONToken.COMMA) {
  191. ch = lexer.ch;
  192. if (ch == '[') {
  193. int index = ++lexer.bp;
  194. lexer.ch = (index >= lexer.len ? //
  195. JSONLexer.EOI //
  196. : lexer.text.charAt(index));
  197. lexer.token = JSONToken.LBRACKET;
  198. } else if (ch == '{') {
  199. int index = ++lexer.bp;
  200. lexer.ch = (index >= lexer.len ? //
  201. JSONLexer.EOI //
  202. : lexer.text.charAt(index));
  203. lexer.token = JSONToken.LBRACE;
  204. } else if (ch == '"') {
  205. lexer.scanString();
  206. } else {
  207. lexer.nextToken();
  208. }
  209. continue;
  210. }
  211. }
  212. if (lexer.ch == ',') {
  213. int index = ++lexer.bp;
  214. lexer.ch = (index >= lexer.len ? //
  215. JSONLexer.EOI //
  216. : lexer.text.charAt(index));
  217. lexer.token = JSONToken.COMMA;
  218. } else {
  219. lexer.nextToken();
  220. }
  221. }
  222. }