/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java

https://github.com/flydream/fastjson · Java · 443 lines · 356 code · 68 blank · 19 comment · 67 complexity · 9243e5186aee4258deeb0db67ace69e8 MD5 · raw file

  1. /*
  2. * Copyright 1999-2101 Alibaba Group.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.alibaba.fastjson.parser;
  17. import java.awt.Color;
  18. import java.awt.Font;
  19. import java.awt.Point;
  20. import java.awt.Rectangle;
  21. import java.io.File;
  22. import java.lang.reflect.Field;
  23. import java.lang.reflect.Modifier;
  24. import java.lang.reflect.ParameterizedType;
  25. import java.lang.reflect.Type;
  26. import java.math.BigDecimal;
  27. import java.math.BigInteger;
  28. import java.net.Inet4Address;
  29. import java.net.Inet6Address;
  30. import java.net.InetAddress;
  31. import java.net.InetSocketAddress;
  32. import java.net.URI;
  33. import java.net.URL;
  34. import java.nio.charset.Charset;
  35. import java.util.ArrayList;
  36. import java.util.Collection;
  37. import java.util.Collections;
  38. import java.util.HashMap;
  39. import java.util.HashSet;
  40. import java.util.LinkedHashMap;
  41. import java.util.List;
  42. import java.util.Locale;
  43. import java.util.Map;
  44. import java.util.Set;
  45. import java.util.TimeZone;
  46. import java.util.TreeMap;
  47. import java.util.UUID;
  48. import java.util.concurrent.ConcurrentHashMap;
  49. import java.util.concurrent.ConcurrentMap;
  50. import java.util.concurrent.atomic.AtomicIntegerArray;
  51. import java.util.concurrent.atomic.AtomicLongArray;
  52. import java.util.regex.Pattern;
  53. import com.alibaba.fastjson.JSONArray;
  54. import com.alibaba.fastjson.JSONException;
  55. import com.alibaba.fastjson.JSONObject;
  56. import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory;
  57. import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;
  58. import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer;
  59. import com.alibaba.fastjson.parser.deserializer.ArrayListStringDeserializer;
  60. import com.alibaba.fastjson.parser.deserializer.ArrayListStringFieldDeserializer;
  61. import com.alibaba.fastjson.parser.deserializer.ArrayListTypeDeserializer;
  62. import com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer;
  63. import com.alibaba.fastjson.parser.deserializer.AtomicIntegerArrayDeserializer;
  64. import com.alibaba.fastjson.parser.deserializer.AtomicLongArrayDeserializer;
  65. import com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer;
  66. import com.alibaba.fastjson.parser.deserializer.BigDecimalDeserializer;
  67. import com.alibaba.fastjson.parser.deserializer.BigIntegerDeserializer;
  68. import com.alibaba.fastjson.parser.deserializer.BooleanDeserializer;
  69. import com.alibaba.fastjson.parser.deserializer.BooleanFieldDeserializer;
  70. import com.alibaba.fastjson.parser.deserializer.ByteDeserializer;
  71. import com.alibaba.fastjson.parser.deserializer.CharArrayDeserializer;
  72. import com.alibaba.fastjson.parser.deserializer.CharacterDeserializer;
  73. import com.alibaba.fastjson.parser.deserializer.CharsetDeserializer;
  74. import com.alibaba.fastjson.parser.deserializer.ClassDerializer;
  75. import com.alibaba.fastjson.parser.deserializer.CollectionDeserializer;
  76. import com.alibaba.fastjson.parser.deserializer.ColorDeserializer;
  77. import com.alibaba.fastjson.parser.deserializer.ConcurrentHashMapDeserializer;
  78. import com.alibaba.fastjson.parser.deserializer.DateDeserializer;
  79. import com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer;
  80. import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer;
  81. import com.alibaba.fastjson.parser.deserializer.DoubleDeserializer;
  82. import com.alibaba.fastjson.parser.deserializer.EnumDeserializer;
  83. import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
  84. import com.alibaba.fastjson.parser.deserializer.FileDeserializer;
  85. import com.alibaba.fastjson.parser.deserializer.FloatDeserializer;
  86. import com.alibaba.fastjson.parser.deserializer.FontDeserializer;
  87. import com.alibaba.fastjson.parser.deserializer.HashMapDeserializer;
  88. import com.alibaba.fastjson.parser.deserializer.InetAddressDeserializer;
  89. import com.alibaba.fastjson.parser.deserializer.InetSocketAddressDeserializer;
  90. import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer;
  91. import com.alibaba.fastjson.parser.deserializer.IntegerFieldDeserializer;
  92. import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer;
  93. import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer;
  94. import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
  95. import com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer;
  96. import com.alibaba.fastjson.parser.deserializer.LinkedHashMapDeserializer;
  97. import com.alibaba.fastjson.parser.deserializer.LocaleDeserializer;
  98. import com.alibaba.fastjson.parser.deserializer.LongDeserializer;
  99. import com.alibaba.fastjson.parser.deserializer.LongFieldDeserializer;
  100. import com.alibaba.fastjson.parser.deserializer.NumberDeserializer;
  101. import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
  102. import com.alibaba.fastjson.parser.deserializer.PatternDeserializer;
  103. import com.alibaba.fastjson.parser.deserializer.PointDeserializer;
  104. import com.alibaba.fastjson.parser.deserializer.RectangleDeserializer;
  105. import com.alibaba.fastjson.parser.deserializer.ShortDeserializer;
  106. import com.alibaba.fastjson.parser.deserializer.SqlDateDeserializer;
  107. import com.alibaba.fastjson.parser.deserializer.StackTraceElementDeserializer;
  108. import com.alibaba.fastjson.parser.deserializer.StringDeserializer;
  109. import com.alibaba.fastjson.parser.deserializer.StringFieldDeserializer;
  110. import com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer;
  111. import com.alibaba.fastjson.parser.deserializer.TimeDeserializer;
  112. import com.alibaba.fastjson.parser.deserializer.TimeZoneDeserializer;
  113. import com.alibaba.fastjson.parser.deserializer.TimestampDeserializer;
  114. import com.alibaba.fastjson.parser.deserializer.TreeMapDeserializer;
  115. import com.alibaba.fastjson.parser.deserializer.URIDeserializer;
  116. import com.alibaba.fastjson.parser.deserializer.URLDeserializer;
  117. import com.alibaba.fastjson.parser.deserializer.UUIDDeserializer;
  118. import com.alibaba.fastjson.util.ASMUtils;
  119. import com.alibaba.fastjson.util.FieldInfo;
  120. import com.alibaba.fastjson.util.IdentityHashMap;
  121. import com.alibaba.fastjson.util.ServiceLoader;
  122. /**
  123. * @author wenshao<szujobs@hotmail.com>
  124. */
  125. public class ParserConfig {
  126. public static ParserConfig getGlobalInstance() {
  127. return global;
  128. }
  129. private final Set<Class<?>> primitiveClasses = new HashSet<Class<?>>();
  130. private static ParserConfig global = new ParserConfig();
  131. private final IdentityHashMap<Type, ObjectDeserializer> derializers = new IdentityHashMap<Type, ObjectDeserializer>();
  132. private DefaultObjectDeserializer defaultSerializer = new DefaultObjectDeserializer();
  133. private boolean asmEnable = !ASMUtils.isAndroid();
  134. protected final SymbolTable symbolTable = new SymbolTable();
  135. public DefaultObjectDeserializer getDefaultSerializer() {
  136. return defaultSerializer;
  137. }
  138. public ParserConfig(){
  139. primitiveClasses.add(boolean.class);
  140. primitiveClasses.add(Boolean.class);
  141. primitiveClasses.add(char.class);
  142. primitiveClasses.add(Character.class);
  143. primitiveClasses.add(byte.class);
  144. primitiveClasses.add(Byte.class);
  145. primitiveClasses.add(short.class);
  146. primitiveClasses.add(Short.class);
  147. primitiveClasses.add(int.class);
  148. primitiveClasses.add(Integer.class);
  149. primitiveClasses.add(long.class);
  150. primitiveClasses.add(Long.class);
  151. primitiveClasses.add(float.class);
  152. primitiveClasses.add(Float.class);
  153. primitiveClasses.add(double.class);
  154. primitiveClasses.add(Double.class);
  155. primitiveClasses.add(BigInteger.class);
  156. primitiveClasses.add(BigDecimal.class);
  157. primitiveClasses.add(String.class);
  158. primitiveClasses.add(java.util.Date.class);
  159. primitiveClasses.add(java.sql.Date.class);
  160. primitiveClasses.add(java.sql.Time.class);
  161. primitiveClasses.add(java.sql.Timestamp.class);
  162. derializers.put(java.sql.Timestamp.class, TimestampDeserializer.instance);
  163. derializers.put(java.sql.Date.class, SqlDateDeserializer.instance);
  164. derializers.put(java.sql.Time.class, TimeDeserializer.instance);
  165. derializers.put(java.util.Date.class, DateDeserializer.instance);
  166. derializers.put(JSONObject.class, JSONObjectDeserializer.instance);
  167. derializers.put(JSONArray.class, JSONArrayDeserializer.instance);
  168. derializers.put(Map.class, HashMapDeserializer.instance);
  169. derializers.put(HashMap.class, HashMapDeserializer.instance);
  170. derializers.put(LinkedHashMap.class, LinkedHashMapDeserializer.instance);
  171. derializers.put(TreeMap.class, TreeMapDeserializer.instance);
  172. derializers.put(ConcurrentMap.class, ConcurrentHashMapDeserializer.instance);
  173. derializers.put(ConcurrentHashMap.class, ConcurrentHashMapDeserializer.instance);
  174. derializers.put(Collection.class, CollectionDeserializer.instance);
  175. derializers.put(List.class, CollectionDeserializer.instance);
  176. derializers.put(ArrayList.class, CollectionDeserializer.instance);
  177. derializers.put(Object.class, JavaObjectDeserializer.instance);
  178. derializers.put(String.class, StringDeserializer.instance);
  179. derializers.put(char.class, CharacterDeserializer.instance);
  180. derializers.put(Character.class, CharacterDeserializer.instance);
  181. derializers.put(byte.class, ByteDeserializer.instance);
  182. derializers.put(Byte.class, ByteDeserializer.instance);
  183. derializers.put(short.class, ShortDeserializer.instance);
  184. derializers.put(Short.class, ShortDeserializer.instance);
  185. derializers.put(int.class, IntegerDeserializer.instance);
  186. derializers.put(Integer.class, IntegerDeserializer.instance);
  187. derializers.put(long.class, LongDeserializer.instance);
  188. derializers.put(Long.class, LongDeserializer.instance);
  189. derializers.put(BigInteger.class, BigIntegerDeserializer.instance);
  190. derializers.put(BigDecimal.class, BigDecimalDeserializer.instance);
  191. derializers.put(float.class, FloatDeserializer.instance);
  192. derializers.put(Float.class, FloatDeserializer.instance);
  193. derializers.put(double.class, DoubleDeserializer.instance);
  194. derializers.put(Double.class, DoubleDeserializer.instance);
  195. derializers.put(boolean.class, BooleanDeserializer.instance);
  196. derializers.put(Boolean.class, BooleanDeserializer.instance);
  197. derializers.put(Class.class, ClassDerializer.instance);
  198. derializers.put(char[].class, CharArrayDeserializer.instance);
  199. derializers.put(UUID.class, UUIDDeserializer.instance);
  200. derializers.put(TimeZone.class, TimeZoneDeserializer.instance);
  201. derializers.put(Locale.class, LocaleDeserializer.instance);
  202. derializers.put(InetAddress.class, InetAddressDeserializer.instance);
  203. derializers.put(Inet4Address.class, InetAddressDeserializer.instance);
  204. derializers.put(Inet6Address.class, InetAddressDeserializer.instance);
  205. derializers.put(InetSocketAddress.class, InetSocketAddressDeserializer.instance);
  206. derializers.put(File.class, FileDeserializer.instance);
  207. derializers.put(URI.class, URIDeserializer.instance);
  208. derializers.put(URL.class, URLDeserializer.instance);
  209. derializers.put(Pattern.class, PatternDeserializer.instance);
  210. derializers.put(Charset.class, CharsetDeserializer.instance);
  211. derializers.put(Number.class, NumberDeserializer.instance);
  212. derializers.put(AtomicIntegerArray.class, AtomicIntegerArrayDeserializer.instance);
  213. derializers.put(AtomicLongArray.class, AtomicLongArrayDeserializer.instance);
  214. derializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance);
  215. derializers.put(Color.class, ColorDeserializer.instance);
  216. derializers.put(Font.class, FontDeserializer.instance);
  217. derializers.put(Point.class, PointDeserializer.instance);
  218. derializers.put(Rectangle.class, RectangleDeserializer.instance);
  219. }
  220. public boolean isAsmEnable() {
  221. return asmEnable;
  222. }
  223. public void setAsmEnable(boolean asmEnable) {
  224. this.asmEnable = asmEnable;
  225. }
  226. public SymbolTable getSymbolTable() {
  227. return symbolTable;
  228. }
  229. public IdentityHashMap<Type, ObjectDeserializer> getDerializers() {
  230. return derializers;
  231. }
  232. public ObjectDeserializer getDeserializer(Type type) {
  233. ObjectDeserializer derializer = this.derializers.get(type);
  234. if (derializer != null) {
  235. return derializer;
  236. }
  237. if (type instanceof Class<?>) {
  238. return getDeserializer((Class<?>) type, type);
  239. }
  240. if (type instanceof ParameterizedType) {
  241. Type rawType = ((ParameterizedType) type).getRawType();
  242. return getDeserializer((Class<?>) rawType, type);
  243. }
  244. return this.defaultSerializer;
  245. }
  246. public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
  247. ObjectDeserializer derializer = derializers.get(type);
  248. if (derializer != null) {
  249. return derializer;
  250. }
  251. final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  252. for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) {
  253. for (Type forType : autowired.getAutowiredFor()) {
  254. derializers.put(forType, autowired);
  255. }
  256. }
  257. derializer = derializers.get(type);
  258. if (derializer != null) {
  259. return derializer;
  260. }
  261. if (clazz.isEnum()) {
  262. derializer = new EnumDeserializer(clazz);
  263. } else if (clazz.isArray()) {
  264. return ArrayDeserializer.instance;
  265. } else if (clazz == Set.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) {
  266. if (type instanceof ParameterizedType) {
  267. Type itemType = ((ParameterizedType) type).getActualTypeArguments()[0];
  268. if (itemType == String.class) {
  269. derializer = ArrayListStringDeserializer.instance;
  270. } else {
  271. derializer = new ArrayListTypeDeserializer(clazz, itemType);
  272. }
  273. } else {
  274. derializer = CollectionDeserializer.instance;
  275. }
  276. } else if (Collection.class.isAssignableFrom(clazz)) {
  277. derializer = CollectionDeserializer.instance;
  278. } else if (Map.class.isAssignableFrom(clazz)) {
  279. derializer = this.defaultSerializer;
  280. } else if (Throwable.class.isAssignableFrom(clazz)) {
  281. derializer = new ThrowableDeserializer(this, clazz);
  282. } else {
  283. derializer = createJavaBeanDeserializer(clazz);
  284. }
  285. putDeserializer(type, derializer);
  286. return derializer;
  287. }
  288. public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz) {
  289. if (clazz == Class.class) {
  290. return this.defaultSerializer;
  291. }
  292. if (!Modifier.isPublic(clazz.getModifiers())) {
  293. return new JavaBeanDeserializer(this, clazz);
  294. }
  295. if (!asmEnable) {
  296. return new JavaBeanDeserializer(this, clazz);
  297. }
  298. try {
  299. return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz);
  300. } catch (Exception e) {
  301. throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
  302. }
  303. }
  304. public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
  305. boolean asmEnable = this.asmEnable;
  306. if (!Modifier.isPublic(clazz.getModifiers())) {
  307. asmEnable = false;
  308. }
  309. if (fieldInfo.getFieldClass() == Class.class) {
  310. asmEnable = false;
  311. }
  312. if (!asmEnable) {
  313. return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo);
  314. }
  315. try {
  316. return ASMDeserializerFactory.getInstance().createFieldDeserializer(mapping, clazz, fieldInfo);
  317. } catch (Throwable e) {
  318. // TODO Auto-generated catch block
  319. e.printStackTrace();
  320. }
  321. return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo);
  322. }
  323. public FieldDeserializer createFieldDeserializerWithoutASM(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
  324. Class<?> fieldClass = fieldInfo.getFieldClass();
  325. if (fieldClass == boolean.class || fieldClass == Boolean.class) {
  326. return new BooleanFieldDeserializer(mapping, clazz, fieldInfo);
  327. }
  328. if (fieldClass == int.class || fieldClass == Integer.class) {
  329. return new IntegerFieldDeserializer(mapping, clazz, fieldInfo);
  330. }
  331. if (fieldClass == long.class || fieldClass == Long.class) {
  332. return new LongFieldDeserializer(mapping, clazz, fieldInfo);
  333. }
  334. if (fieldClass == String.class) {
  335. return new StringFieldDeserializer(mapping, clazz, fieldInfo);
  336. }
  337. if (fieldClass == List.class || fieldClass == ArrayList.class) {
  338. Type fieldType = fieldInfo.getFieldType();
  339. if (fieldType instanceof ParameterizedType) {
  340. Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  341. if (itemType == String.class) {
  342. return new ArrayListStringFieldDeserializer(mapping, clazz, fieldInfo);
  343. }
  344. }
  345. return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
  346. }
  347. return new DefaultFieldDeserializer(mapping, clazz, fieldInfo);
  348. }
  349. public void putDeserializer(Type type, ObjectDeserializer deserializer) {
  350. derializers.put(type, deserializer);
  351. }
  352. public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) {
  353. return getDeserializer(fieldInfo.getFieldClass(), fieldInfo.getFieldType());
  354. }
  355. public boolean isPrimitive(Class<?> clazz) {
  356. return primitiveClasses.contains(clazz);
  357. }
  358. public static Field getField(Class<?> clazz, String fieldName) {
  359. try {
  360. return clazz.getDeclaredField(fieldName);
  361. } catch (Exception e) {
  362. return null;
  363. }
  364. }
  365. public Map<String, FieldDeserializer> getFieldDeserializers(Class<?> clazz) {
  366. ObjectDeserializer deserizer = getDeserializer(clazz);
  367. if (deserizer instanceof JavaBeanDeserializer) {
  368. return ((JavaBeanDeserializer) deserizer).getFieldDeserializerMap();
  369. } else if (deserizer instanceof ASMJavaBeanDeserializer) {
  370. return ((ASMJavaBeanDeserializer) deserizer).getInnterSerializer().getFieldDeserializerMap();
  371. } else {
  372. return Collections.emptyMap();
  373. }
  374. }
  375. }