PageRenderTime 100ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/xiejuntao/xdesktop
Java | 534 lines | 429 code | 81 blank | 24 comment | 101 complexity | 653817d27e09123e5cad461b81acf688 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.io.Closeable;
  18. import java.io.File;
  19. import java.io.Serializable;
  20. import java.lang.reflect.Field;
  21. import java.lang.reflect.Modifier;
  22. import java.lang.reflect.ParameterizedType;
  23. import java.lang.reflect.Type;
  24. import java.lang.reflect.TypeVariable;
  25. import java.lang.reflect.WildcardType;
  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.text.SimpleDateFormat;
  36. import java.util.ArrayList;
  37. import java.util.Calendar;
  38. import java.util.Collection;
  39. import java.util.Collections;
  40. import java.util.HashMap;
  41. import java.util.HashSet;
  42. import java.util.LinkedHashMap;
  43. import java.util.List;
  44. import java.util.Locale;
  45. import java.util.Map;
  46. import java.util.Set;
  47. import java.util.TimeZone;
  48. import java.util.TreeMap;
  49. import java.util.UUID;
  50. import java.util.concurrent.ConcurrentHashMap;
  51. import java.util.concurrent.ConcurrentMap;
  52. import java.util.concurrent.atomic.AtomicIntegerArray;
  53. import java.util.concurrent.atomic.AtomicLongArray;
  54. import java.util.regex.Pattern;
  55. import com.alibaba.fastjson.JSONArray;
  56. import com.alibaba.fastjson.JSONException;
  57. import com.alibaba.fastjson.JSONObject;
  58. import com.alibaba.fastjson.asm.ASMException;
  59. import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory;
  60. import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;
  61. import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer;
  62. import com.alibaba.fastjson.parser.deserializer.ArrayListStringDeserializer;
  63. import com.alibaba.fastjson.parser.deserializer.ArrayListStringFieldDeserializer;
  64. import com.alibaba.fastjson.parser.deserializer.ArrayListTypeDeserializer;
  65. import com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer;
  66. import com.alibaba.fastjson.parser.deserializer.AtomicIntegerArrayDeserializer;
  67. import com.alibaba.fastjson.parser.deserializer.AtomicLongArrayDeserializer;
  68. import com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer;
  69. import com.alibaba.fastjson.parser.deserializer.BigDecimalDeserializer;
  70. import com.alibaba.fastjson.parser.deserializer.BigIntegerDeserializer;
  71. import com.alibaba.fastjson.parser.deserializer.BooleanDeserializer;
  72. import com.alibaba.fastjson.parser.deserializer.BooleanFieldDeserializer;
  73. import com.alibaba.fastjson.parser.deserializer.CalendarDeserializer;
  74. import com.alibaba.fastjson.parser.deserializer.CharArrayDeserializer;
  75. import com.alibaba.fastjson.parser.deserializer.CharacterDeserializer;
  76. import com.alibaba.fastjson.parser.deserializer.CharsetDeserializer;
  77. import com.alibaba.fastjson.parser.deserializer.ClassDerializer;
  78. import com.alibaba.fastjson.parser.deserializer.CollectionDeserializer;
  79. import com.alibaba.fastjson.parser.deserializer.ColorDeserializer;
  80. import com.alibaba.fastjson.parser.deserializer.DateDeserializer;
  81. import com.alibaba.fastjson.parser.deserializer.DateFormatDeserializer;
  82. import com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer;
  83. import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer;
  84. import com.alibaba.fastjson.parser.deserializer.EnumDeserializer;
  85. import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
  86. import com.alibaba.fastjson.parser.deserializer.FileDeserializer;
  87. import com.alibaba.fastjson.parser.deserializer.FloatDeserializer;
  88. import com.alibaba.fastjson.parser.deserializer.FontDeserializer;
  89. import com.alibaba.fastjson.parser.deserializer.InetAddressDeserializer;
  90. import com.alibaba.fastjson.parser.deserializer.InetSocketAddressDeserializer;
  91. import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer;
  92. import com.alibaba.fastjson.parser.deserializer.IntegerFieldDeserializer;
  93. import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer;
  94. import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer;
  95. import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
  96. import com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer;
  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.MapDeserializer;
  101. import com.alibaba.fastjson.parser.deserializer.NumberDeserializer;
  102. import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
  103. import com.alibaba.fastjson.parser.deserializer.PatternDeserializer;
  104. import com.alibaba.fastjson.parser.deserializer.PointDeserializer;
  105. import com.alibaba.fastjson.parser.deserializer.RectangleDeserializer;
  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.URIDeserializer;
  115. import com.alibaba.fastjson.parser.deserializer.URLDeserializer;
  116. import com.alibaba.fastjson.parser.deserializer.UUIDDeserializer;
  117. import com.alibaba.fastjson.util.ASMUtils;
  118. import com.alibaba.fastjson.util.DeserializeBeanInfo;
  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(SimpleDateFormat.class, DateFormatDeserializer.instance);
  163. derializers.put(java.sql.Timestamp.class, TimestampDeserializer.instance);
  164. derializers.put(java.sql.Date.class, SqlDateDeserializer.instance);
  165. derializers.put(java.sql.Time.class, TimeDeserializer.instance);
  166. derializers.put(java.util.Date.class, DateDeserializer.instance);
  167. derializers.put(Calendar.class, CalendarDeserializer.instance);
  168. derializers.put(JSONObject.class, JSONObjectDeserializer.instance);
  169. derializers.put(JSONArray.class, JSONArrayDeserializer.instance);
  170. derializers.put(Map.class, MapDeserializer.instance);
  171. derializers.put(HashMap.class, MapDeserializer.instance);
  172. derializers.put(LinkedHashMap.class, MapDeserializer.instance);
  173. derializers.put(TreeMap.class, MapDeserializer.instance);
  174. derializers.put(ConcurrentMap.class, MapDeserializer.instance);
  175. derializers.put(ConcurrentHashMap.class, MapDeserializer.instance);
  176. derializers.put(Collection.class, CollectionDeserializer.instance);
  177. derializers.put(List.class, CollectionDeserializer.instance);
  178. derializers.put(ArrayList.class, CollectionDeserializer.instance);
  179. derializers.put(Object.class, JavaObjectDeserializer.instance);
  180. derializers.put(String.class, StringDeserializer.instance);
  181. derializers.put(char.class, CharacterDeserializer.instance);
  182. derializers.put(Character.class, CharacterDeserializer.instance);
  183. derializers.put(byte.class, NumberDeserializer.instance);
  184. derializers.put(Byte.class, NumberDeserializer.instance);
  185. derializers.put(short.class, NumberDeserializer.instance);
  186. derializers.put(Short.class, NumberDeserializer.instance);
  187. derializers.put(int.class, IntegerDeserializer.instance);
  188. derializers.put(Integer.class, IntegerDeserializer.instance);
  189. derializers.put(long.class, LongDeserializer.instance);
  190. derializers.put(Long.class, LongDeserializer.instance);
  191. derializers.put(BigInteger.class, BigIntegerDeserializer.instance);
  192. derializers.put(BigDecimal.class, BigDecimalDeserializer.instance);
  193. derializers.put(float.class, FloatDeserializer.instance);
  194. derializers.put(Float.class, FloatDeserializer.instance);
  195. derializers.put(double.class, NumberDeserializer.instance);
  196. derializers.put(Double.class, NumberDeserializer.instance);
  197. derializers.put(boolean.class, BooleanDeserializer.instance);
  198. derializers.put(Boolean.class, BooleanDeserializer.instance);
  199. derializers.put(Class.class, ClassDerializer.instance);
  200. derializers.put(char[].class, CharArrayDeserializer.instance);
  201. derializers.put(UUID.class, UUIDDeserializer.instance);
  202. derializers.put(TimeZone.class, TimeZoneDeserializer.instance);
  203. derializers.put(Locale.class, LocaleDeserializer.instance);
  204. derializers.put(InetAddress.class, InetAddressDeserializer.instance);
  205. derializers.put(Inet4Address.class, InetAddressDeserializer.instance);
  206. derializers.put(Inet6Address.class, InetAddressDeserializer.instance);
  207. derializers.put(InetSocketAddress.class, InetSocketAddressDeserializer.instance);
  208. derializers.put(File.class, FileDeserializer.instance);
  209. derializers.put(URI.class, URIDeserializer.instance);
  210. derializers.put(URL.class, URLDeserializer.instance);
  211. derializers.put(Pattern.class, PatternDeserializer.instance);
  212. derializers.put(Charset.class, CharsetDeserializer.instance);
  213. derializers.put(Number.class, NumberDeserializer.instance);
  214. derializers.put(AtomicIntegerArray.class, AtomicIntegerArrayDeserializer.instance);
  215. derializers.put(AtomicLongArray.class, AtomicLongArrayDeserializer.instance);
  216. derializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance);
  217. derializers.put(Serializable.class, defaultSerializer);
  218. derializers.put(Cloneable.class, defaultSerializer);
  219. derializers.put(Comparable.class, defaultSerializer);
  220. derializers.put(Closeable.class, defaultSerializer);
  221. try {
  222. derializers.put(Class.forName("java.awt.Point"), PointDeserializer.instance);
  223. derializers.put(Class.forName("java.awt.Font"), FontDeserializer.instance);
  224. derializers.put(Class.forName("java.awt.Rectangle"), RectangleDeserializer.instance);
  225. derializers.put(Class.forName("java.awt.Color"), ColorDeserializer.instance);
  226. } catch (Throwable e) {
  227. // skip
  228. }
  229. }
  230. public boolean isAsmEnable() {
  231. return asmEnable;
  232. }
  233. public void setAsmEnable(boolean asmEnable) {
  234. this.asmEnable = asmEnable;
  235. }
  236. public SymbolTable getSymbolTable() {
  237. return symbolTable;
  238. }
  239. public IdentityHashMap<Type, ObjectDeserializer> getDerializers() {
  240. return derializers;
  241. }
  242. public ObjectDeserializer getDeserializer(Type type) {
  243. ObjectDeserializer derializer = this.derializers.get(type);
  244. if (derializer != null) {
  245. return derializer;
  246. }
  247. if (type instanceof Class<?>) {
  248. return getDeserializer((Class<?>) type, type);
  249. }
  250. if (type instanceof ParameterizedType) {
  251. Type rawType = ((ParameterizedType) type).getRawType();
  252. if (rawType instanceof Class<?>) {
  253. return getDeserializer((Class<?>) rawType, type);
  254. } else {
  255. return getDeserializer(rawType);
  256. }
  257. }
  258. return this.defaultSerializer;
  259. }
  260. public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
  261. ObjectDeserializer derializer = derializers.get(type);
  262. if (derializer != null) {
  263. return derializer;
  264. }
  265. if (type == null) {
  266. type = clazz;
  267. }
  268. derializer = derializers.get(type);
  269. if (derializer != null) {
  270. return derializer;
  271. }
  272. if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
  273. derializer = derializers.get(clazz);
  274. }
  275. if (derializer != null) {
  276. return derializer;
  277. }
  278. final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  279. try {
  280. for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class,
  281. classLoader)) {
  282. for (Type forType : autowired.getAutowiredFor()) {
  283. derializers.put(forType, autowired);
  284. }
  285. }
  286. } catch (Exception ex) {
  287. // skip
  288. }
  289. derializer = derializers.get(type);
  290. if (derializer != null) {
  291. return derializer;
  292. }
  293. if (clazz.isEnum()) {
  294. derializer = new EnumDeserializer(clazz);
  295. } else if (clazz.isArray()) {
  296. return ArrayDeserializer.instance;
  297. } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class
  298. || clazz == ArrayList.class) {
  299. if (type instanceof ParameterizedType) {
  300. Type itemType = ((ParameterizedType) type).getActualTypeArguments()[0];
  301. if (itemType == String.class) {
  302. derializer = ArrayListStringDeserializer.instance;
  303. } else {
  304. derializer = new ArrayListTypeDeserializer(clazz, itemType);
  305. }
  306. } else {
  307. derializer = CollectionDeserializer.instance;
  308. }
  309. } else if (Collection.class.isAssignableFrom(clazz)) {
  310. derializer = CollectionDeserializer.instance;
  311. } else if (Map.class.isAssignableFrom(clazz)) {
  312. derializer = MapDeserializer.instance;
  313. } else if (Throwable.class.isAssignableFrom(clazz)) {
  314. derializer = new ThrowableDeserializer(this, clazz);
  315. } else {
  316. derializer = createJavaBeanDeserializer(clazz, type);
  317. }
  318. putDeserializer(type, derializer);
  319. return derializer;
  320. }
  321. public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
  322. if (clazz == Class.class) {
  323. return this.defaultSerializer;
  324. }
  325. boolean asmEnable = this.asmEnable;
  326. if (asmEnable && !Modifier.isPublic(clazz.getModifiers())) {
  327. asmEnable = false;
  328. }
  329. if (clazz.getTypeParameters().length != 0) {
  330. asmEnable = false;
  331. }
  332. if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) {
  333. asmEnable = false;
  334. }
  335. if (asmEnable) {
  336. DeserializeBeanInfo beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);
  337. if (beanInfo.getFieldList().size() > 200) {
  338. asmEnable = false;
  339. }
  340. for (FieldInfo fieldInfo : beanInfo.getFieldList()) {
  341. if (fieldInfo.isGetOnly()) {
  342. asmEnable = false;
  343. break;
  344. }
  345. Class<?> fieldClass = fieldInfo.getFieldClass();
  346. if (!Modifier.isPublic(fieldClass.getModifiers())) {
  347. asmEnable = false;
  348. break;
  349. }
  350. if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) {
  351. asmEnable = false;
  352. }
  353. }
  354. }
  355. if (asmEnable) {
  356. if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
  357. asmEnable = false;
  358. }
  359. }
  360. if (!asmEnable) {
  361. return new JavaBeanDeserializer(this, clazz, type);
  362. }
  363. try {
  364. return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz, type);
  365. // } catch (VerifyError e) {
  366. // e.printStackTrace();
  367. // return new JavaBeanDeserializer(this, clazz, type);
  368. } catch (NoSuchMethodException error) {
  369. return new JavaBeanDeserializer(this, clazz, type);
  370. } catch (ASMException asmError) {
  371. return new JavaBeanDeserializer(this, clazz, type);
  372. } catch (Exception e) {
  373. throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
  374. }
  375. }
  376. public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
  377. boolean asmEnable = this.asmEnable;
  378. if (!Modifier.isPublic(clazz.getModifiers())) {
  379. asmEnable = false;
  380. }
  381. if (fieldInfo.getFieldClass() == Class.class) {
  382. asmEnable = false;
  383. }
  384. if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) {
  385. asmEnable = false;
  386. }
  387. if (!asmEnable) {
  388. return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo);
  389. }
  390. try {
  391. return ASMDeserializerFactory.getInstance().createFieldDeserializer(mapping, clazz, fieldInfo);
  392. } catch (Throwable e) {
  393. // skip
  394. }
  395. return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo);
  396. }
  397. public FieldDeserializer createFieldDeserializerWithoutASM(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
  398. Class<?> fieldClass = fieldInfo.getFieldClass();
  399. if (fieldClass == boolean.class || fieldClass == Boolean.class) {
  400. return new BooleanFieldDeserializer(mapping, clazz, fieldInfo);
  401. }
  402. if (fieldClass == int.class || fieldClass == Integer.class) {
  403. return new IntegerFieldDeserializer(mapping, clazz, fieldInfo);
  404. }
  405. if (fieldClass == long.class || fieldClass == Long.class) {
  406. return new LongFieldDeserializer(mapping, clazz, fieldInfo);
  407. }
  408. if (fieldClass == String.class) {
  409. return new StringFieldDeserializer(mapping, clazz, fieldInfo);
  410. }
  411. if (fieldClass == List.class || fieldClass == ArrayList.class) {
  412. Type fieldType = fieldInfo.getFieldType();
  413. if (fieldType instanceof ParameterizedType) {
  414. Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  415. if (itemType == String.class) {
  416. return new ArrayListStringFieldDeserializer(mapping, clazz, fieldInfo);
  417. }
  418. }
  419. return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
  420. }
  421. return new DefaultFieldDeserializer(mapping, clazz, fieldInfo);
  422. }
  423. public void putDeserializer(Type type, ObjectDeserializer deserializer) {
  424. derializers.put(type, deserializer);
  425. }
  426. public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) {
  427. return getDeserializer(fieldInfo.getFieldClass(), fieldInfo.getFieldType());
  428. }
  429. public boolean isPrimitive(Class<?> clazz) {
  430. return primitiveClasses.contains(clazz);
  431. }
  432. public static Field getField(Class<?> clazz, String fieldName) {
  433. for (Field item : clazz.getDeclaredFields()) {
  434. if (fieldName.equals(item.getName())) {
  435. return item;
  436. }
  437. }
  438. if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
  439. return getField(clazz.getSuperclass(), fieldName);
  440. }
  441. return null;
  442. }
  443. public Map<String, FieldDeserializer> getFieldDeserializers(Class<?> clazz) {
  444. ObjectDeserializer deserizer = getDeserializer(clazz);
  445. if (deserizer instanceof JavaBeanDeserializer) {
  446. return ((JavaBeanDeserializer) deserizer).getFieldDeserializerMap();
  447. } else if (deserizer instanceof ASMJavaBeanDeserializer) {
  448. return ((ASMJavaBeanDeserializer) deserizer).getInnterSerializer().getFieldDeserializerMap();
  449. } else {
  450. return Collections.emptyMap();
  451. }
  452. }
  453. }