PageRenderTime 87ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/util/TypeUtils.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 1049 lines | 805 code | 221 blank | 23 comment | 314 complexity | aeb5b0d6f87ed400647ba9089708bbca 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.util;
  17. import java.lang.reflect.Array;
  18. import java.lang.reflect.Field;
  19. import java.lang.reflect.Method;
  20. import java.lang.reflect.Modifier;
  21. import java.lang.reflect.ParameterizedType;
  22. import java.lang.reflect.Proxy;
  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.text.ParseException;
  29. import java.text.SimpleDateFormat;
  30. import java.util.ArrayList;
  31. import java.util.Calendar;
  32. import java.util.Collection;
  33. import java.util.Collections;
  34. import java.util.Date;
  35. import java.util.HashMap;
  36. import java.util.Iterator;
  37. import java.util.LinkedHashMap;
  38. import java.util.List;
  39. import java.util.Map;
  40. import java.util.concurrent.ConcurrentHashMap;
  41. import java.util.concurrent.ConcurrentMap;
  42. import com.alibaba.fastjson.JSON;
  43. import com.alibaba.fastjson.JSONException;
  44. import com.alibaba.fastjson.JSONObject;
  45. import com.alibaba.fastjson.annotation.JSONField;
  46. import com.alibaba.fastjson.annotation.JSONType;
  47. import com.alibaba.fastjson.parser.ParserConfig;
  48. import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
  49. /**
  50. * @author wenshao<szujobs@hotmail.com>
  51. */
  52. public class TypeUtils {
  53. public static final String castToString(Object value) {
  54. if (value == null) {
  55. return null;
  56. }
  57. return value.toString();
  58. }
  59. public static final Byte castToByte(Object value) {
  60. if (value == null) {
  61. return null;
  62. }
  63. if (value instanceof Number) {
  64. return ((Number) value).byteValue();
  65. }
  66. if (value instanceof String) {
  67. String strVal = (String) value;
  68. if (strVal.length() == 0) {
  69. return null;
  70. }
  71. return Byte.parseByte(strVal);
  72. }
  73. throw new JSONException("can not cast to byte, value : " + value);
  74. }
  75. public static final Character castToChar(Object value) {
  76. if (value == null) {
  77. return null;
  78. }
  79. if (value instanceof Character) {
  80. return (Character) value;
  81. }
  82. if (value instanceof String) {
  83. String strVal = (String) value;
  84. if (strVal.length() == 0) {
  85. return null;
  86. }
  87. if (strVal.length() != 1) {
  88. throw new JSONException("can not cast to byte, value : " + value);
  89. }
  90. return strVal.charAt(0);
  91. }
  92. throw new JSONException("can not cast to byte, value : " + value);
  93. }
  94. public static final Short castToShort(Object value) {
  95. if (value == null) {
  96. return null;
  97. }
  98. if (value instanceof Number) {
  99. return ((Number) value).shortValue();
  100. }
  101. if (value instanceof String) {
  102. String strVal = (String) value;
  103. if (strVal.length() == 0) {
  104. return null;
  105. }
  106. return Short.parseShort(strVal);
  107. }
  108. throw new JSONException("can not cast to short, value : " + value);
  109. }
  110. public static final BigDecimal castToBigDecimal(Object value) {
  111. if (value == null) {
  112. return null;
  113. }
  114. if (value instanceof BigDecimal) {
  115. return (BigDecimal) value;
  116. }
  117. if (value instanceof BigInteger) {
  118. return new BigDecimal((BigInteger) value);
  119. }
  120. String strVal = value.toString();
  121. if (strVal.length() == 0) {
  122. return null;
  123. }
  124. return new BigDecimal(strVal);
  125. }
  126. public static final BigInteger castToBigInteger(Object value) {
  127. if (value == null) {
  128. return null;
  129. }
  130. if (value instanceof BigInteger) {
  131. return (BigInteger) value;
  132. }
  133. if (value instanceof Float || value instanceof Double) {
  134. return BigInteger.valueOf(((Number) value).longValue());
  135. }
  136. String strVal = value.toString();
  137. if (strVal.length() == 0) {
  138. return null;
  139. }
  140. return new BigInteger(strVal);
  141. }
  142. public static final Float castToFloat(Object value) {
  143. if (value == null) {
  144. return null;
  145. }
  146. if (value instanceof Number) {
  147. return ((Number) value).floatValue();
  148. }
  149. if (value instanceof String) {
  150. String strVal = value.toString();
  151. if (strVal.length() == 0) {
  152. return null;
  153. }
  154. return Float.parseFloat(strVal);
  155. }
  156. throw new JSONException("can not cast to float, value : " + value);
  157. }
  158. public static final Double castToDouble(Object value) {
  159. if (value == null) {
  160. return null;
  161. }
  162. if (value instanceof Number) {
  163. return ((Number) value).doubleValue();
  164. }
  165. if (value instanceof String) {
  166. String strVal = value.toString();
  167. if (strVal.length() == 0) {
  168. return null;
  169. }
  170. return Double.parseDouble(strVal);
  171. }
  172. throw new JSONException("can not cast to double, value : " + value);
  173. }
  174. public static final Date castToDate(Object value) {
  175. if (value == null) {
  176. return null;
  177. }
  178. if (value instanceof Calendar) {
  179. return ((Calendar) value).getTime();
  180. }
  181. if (value instanceof Date) {
  182. return (Date) value;
  183. }
  184. long longValue = 0;
  185. if (value instanceof Number) {
  186. longValue = ((Number) value).longValue();
  187. }
  188. if (value instanceof String) {
  189. String strVal = (String) value;
  190. if (strVal.indexOf('-') != -1) {
  191. String format;
  192. if (strVal.length() == JSON.DEFFAULT_DATE_FORMAT.length()) {
  193. format = JSON.DEFFAULT_DATE_FORMAT;
  194. } else if (strVal.length() == 10) {
  195. format = "yyyy-MM-dd";
  196. } else if (strVal.length() == "yyyy-MM-dd HH:mm:ss".length()) {
  197. format = "yyyy-MM-dd HH:mm:ss";
  198. } else {
  199. format = "yyyy-MM-dd HH:mm:ss.SSS";
  200. }
  201. SimpleDateFormat dateFormat = new SimpleDateFormat(format);
  202. try {
  203. return (Date) dateFormat.parse(strVal);
  204. } catch (ParseException e) {
  205. throw new JSONException("can not cast to Date, value : " + strVal);
  206. }
  207. }
  208. if (strVal.length() == 0) {
  209. return null;
  210. }
  211. longValue = Long.parseLong(strVal);
  212. }
  213. if (longValue <= 0) {
  214. throw new JSONException("can not cast to Date, value : " + value);
  215. }
  216. return new Date(longValue);
  217. }
  218. public static final java.sql.Date castToSqlDate(Object value) {
  219. if (value == null) {
  220. return null;
  221. }
  222. if (value instanceof Calendar) {
  223. return new java.sql.Date(((Calendar) value).getTimeInMillis());
  224. }
  225. if (value instanceof java.sql.Date) {
  226. return (java.sql.Date) value;
  227. }
  228. if (value instanceof java.util.Date) {
  229. return new java.sql.Date(((java.util.Date) value).getTime());
  230. }
  231. long longValue = 0;
  232. if (value instanceof Number) {
  233. longValue = ((Number) value).longValue();
  234. }
  235. if (value instanceof String) {
  236. String strVal = (String) value;
  237. if (strVal.length() == 0) {
  238. return null;
  239. }
  240. longValue = Long.parseLong(strVal);
  241. }
  242. if (longValue <= 0) {
  243. throw new JSONException("can not cast to Date, value : " + value);
  244. }
  245. return new java.sql.Date(longValue);
  246. }
  247. public static final java.sql.Timestamp castToTimestamp(Object value) {
  248. if (value == null) {
  249. return null;
  250. }
  251. if (value instanceof Calendar) {
  252. return new java.sql.Timestamp(((Calendar) value).getTimeInMillis());
  253. }
  254. if (value instanceof java.sql.Timestamp) {
  255. return (java.sql.Timestamp) value;
  256. }
  257. if (value instanceof java.util.Date) {
  258. return new java.sql.Timestamp(((java.util.Date) value).getTime());
  259. }
  260. long longValue = 0;
  261. if (value instanceof Number) {
  262. longValue = ((Number) value).longValue();
  263. }
  264. if (value instanceof String) {
  265. String strVal = (String) value;
  266. if (strVal.length() == 0) {
  267. return null;
  268. }
  269. longValue = Long.parseLong(strVal);
  270. }
  271. if (longValue <= 0) {
  272. throw new JSONException("can not cast to Date, value : " + value);
  273. }
  274. return new java.sql.Timestamp(longValue);
  275. }
  276. public static final Long castToLong(Object value) {
  277. if (value == null) {
  278. return null;
  279. }
  280. if (value instanceof Number) {
  281. return ((Number) value).longValue();
  282. }
  283. if (value instanceof String) {
  284. String strVal = (String) value;
  285. if (strVal.length() == 0) {
  286. return null;
  287. }
  288. return Long.parseLong(strVal);
  289. }
  290. throw new JSONException("can not cast to long, value : " + value);
  291. }
  292. public static final Integer castToInt(Object value) {
  293. if (value == null) {
  294. return null;
  295. }
  296. if (value instanceof Integer) {
  297. return (Integer) value;
  298. }
  299. if (value instanceof Number) {
  300. return ((Number) value).intValue();
  301. }
  302. if (value instanceof String) {
  303. String strVal = (String) value;
  304. if (strVal.length() == 0) {
  305. return null;
  306. }
  307. return Integer.parseInt(strVal);
  308. }
  309. throw new JSONException("can not cast to int, value : " + value);
  310. }
  311. public static final byte[] castToBytes(Object value) {
  312. if (value instanceof byte[]) {
  313. return (byte[]) value;
  314. }
  315. if (value instanceof String) {
  316. return Base64.decodeFast((String) value);
  317. }
  318. throw new JSONException("can not cast to int, value : " + value);
  319. }
  320. public static final Boolean castToBoolean(Object value) {
  321. if (value == null) {
  322. return null;
  323. }
  324. if (value instanceof Boolean) {
  325. return (Boolean) value;
  326. }
  327. if (value instanceof Number) {
  328. return ((Number) value).intValue() == 1;
  329. }
  330. if (value instanceof String) {
  331. String str = (String) value;
  332. if (str.length() == 0) {
  333. return null;
  334. }
  335. if ("true".equals(str)) {
  336. return Boolean.TRUE;
  337. }
  338. if ("false".equals(str)) {
  339. return Boolean.FALSE;
  340. }
  341. if ("1".equals(str)) {
  342. return Boolean.TRUE;
  343. }
  344. }
  345. throw new JSONException("can not cast to int, value : " + value);
  346. }
  347. public static final <T> T castToJavaBean(Object obj, Class<T> clazz) {
  348. return cast(obj, clazz, ParserConfig.getGlobalInstance());
  349. }
  350. @SuppressWarnings({ "unchecked", "rawtypes" })
  351. public static final <T> T cast(Object obj, Class<T> clazz, ParserConfig mapping) {
  352. if (obj == null) {
  353. return null;
  354. }
  355. if (clazz == obj.getClass()) {
  356. return (T) obj;
  357. }
  358. if (obj instanceof Map) {
  359. if (clazz == Map.class) {
  360. return (T) obj;
  361. }
  362. return castToJavaBean((Map<String, Object>) obj, clazz, mapping);
  363. }
  364. if (clazz.isArray()) {
  365. if (obj instanceof Collection) {
  366. Collection collection = (Collection) obj;
  367. int index = 0;
  368. Object array = Array.newInstance(clazz.getComponentType(), collection.size());
  369. for (Object item : collection) {
  370. Object value = cast(item, clazz.getComponentType(), mapping);
  371. Array.set(array, index, value);
  372. index++;
  373. }
  374. return (T) array;
  375. }
  376. }
  377. if (clazz.isAssignableFrom(obj.getClass())) {
  378. return (T) obj;
  379. }
  380. if (clazz == boolean.class || clazz == Boolean.class) {
  381. return (T) castToBoolean(obj);
  382. }
  383. if (clazz == byte.class || clazz == Byte.class) {
  384. return (T) castToByte(obj);
  385. }
  386. // if (clazz == char.class || clazz == Character.class) {
  387. // return (T) castToCharacter(obj);
  388. // }
  389. if (clazz == short.class || clazz == Short.class) {
  390. return (T) castToShort(obj);
  391. }
  392. if (clazz == int.class || clazz == Integer.class) {
  393. return (T) castToInt(obj);
  394. }
  395. if (clazz == long.class || clazz == Long.class) {
  396. return (T) castToLong(obj);
  397. }
  398. if (clazz == float.class || clazz == Float.class) {
  399. return (T) castToFloat(obj);
  400. }
  401. if (clazz == double.class || clazz == Double.class) {
  402. return (T) castToDouble(obj);
  403. }
  404. if (clazz == String.class) {
  405. return (T) castToString(obj);
  406. }
  407. if (clazz == BigDecimal.class) {
  408. return (T) castToBigDecimal(obj);
  409. }
  410. if (clazz == BigInteger.class) {
  411. return (T) castToBigInteger(obj);
  412. }
  413. if (clazz == Date.class) {
  414. return (T) castToDate(obj);
  415. }
  416. if (clazz == java.sql.Date.class) {
  417. return (T) castToSqlDate(obj);
  418. }
  419. if (clazz == java.sql.Timestamp.class) {
  420. return (T) castToTimestamp(obj);
  421. }
  422. if (clazz.isEnum()) {
  423. return (T) castToEnum(obj, clazz, mapping);
  424. }
  425. if (Calendar.class.isAssignableFrom(clazz)) {
  426. Date date = castToDate(obj);
  427. Calendar calendar;
  428. if (clazz == Calendar.class) {
  429. calendar = Calendar.getInstance();
  430. } else {
  431. try {
  432. calendar = (Calendar) clazz.newInstance();
  433. } catch (Exception e) {
  434. throw new JSONException("can not cast to : " + clazz.getName(), e);
  435. }
  436. }
  437. calendar.setTime(date);
  438. return (T) calendar;
  439. }
  440. if (obj instanceof String) {
  441. String strVal = (String) obj;
  442. if (strVal.length() == 0) {
  443. return null;
  444. }
  445. }
  446. throw new JSONException("can not cast to : " + clazz.getName());
  447. }
  448. @SuppressWarnings({ "unchecked", "rawtypes" })
  449. public static final <T> T castToEnum(Object obj, Class<T> clazz, ParserConfig mapping) {
  450. try {
  451. if (obj instanceof String) {
  452. String name = (String) obj;
  453. if (name.length() == 0) {
  454. return null;
  455. }
  456. return (T) Enum.valueOf((Class<? extends Enum>) clazz, name);
  457. }
  458. if (obj instanceof Number) {
  459. int ordinal = ((Number) obj).intValue();
  460. Method method = clazz.getMethod("values");
  461. Object[] values = (Object[]) method.invoke(null);
  462. for (Object value : values) {
  463. Enum e = (Enum) value;
  464. if (e.ordinal() == ordinal) {
  465. return (T) e;
  466. }
  467. }
  468. }
  469. } catch (Exception ex) {
  470. throw new JSONException("can not cast to : " + clazz.getName(), ex);
  471. }
  472. throw new JSONException("can not cast to : " + clazz.getName());
  473. }
  474. @SuppressWarnings("unchecked")
  475. public static final <T> T cast(Object obj, Type type, ParserConfig mapping) {
  476. if (obj == null) {
  477. return null;
  478. }
  479. if (type instanceof Class) {
  480. return (T) cast(obj, (Class<T>) type, mapping);
  481. }
  482. if (type instanceof ParameterizedType) {
  483. return (T) cast(obj, (ParameterizedType) type, mapping);
  484. }
  485. if (obj instanceof String) {
  486. String strVal = (String) obj;
  487. if (strVal.length() == 0) {
  488. return null;
  489. }
  490. }
  491. if (type instanceof TypeVariable) {
  492. return (T) obj;
  493. }
  494. throw new JSONException("can not cast to : " + type);
  495. }
  496. @SuppressWarnings({ "rawtypes", "unchecked" })
  497. public static final <T> T cast(Object obj, ParameterizedType type, ParserConfig mapping) {
  498. Type rawTye = type.getRawType();
  499. if (rawTye == List.class || rawTye == ArrayList.class) {
  500. Type itemType = type.getActualTypeArguments()[0];
  501. if (obj instanceof Iterable) {
  502. List list = new ArrayList();
  503. for (Iterator it = ((Iterable) obj).iterator(); it.hasNext();) {
  504. Object item = it.next();
  505. list.add(cast(item, itemType, mapping));
  506. }
  507. return (T) list;
  508. }
  509. }
  510. if (rawTye == Map.class || rawTye == HashMap.class) {
  511. Type keyType = type.getActualTypeArguments()[0];
  512. Type valueType = type.getActualTypeArguments()[1];
  513. if (obj instanceof Map) {
  514. Map map = new HashMap();
  515. for (Map.Entry entry : ((Map<?, ?>) obj).entrySet()) {
  516. Object key = cast(entry.getKey(), keyType, mapping);
  517. Object value = cast(entry.getValue(), valueType, mapping);
  518. map.put(key, value);
  519. }
  520. return (T) map;
  521. }
  522. }
  523. if (obj instanceof String) {
  524. String strVal = (String) obj;
  525. if (strVal.length() == 0) {
  526. return null;
  527. }
  528. }
  529. if (type.getActualTypeArguments().length == 1) {
  530. Type argType = type.getActualTypeArguments()[0];
  531. if (argType instanceof WildcardType) {
  532. return (T) cast(obj, rawTye, mapping);
  533. }
  534. }
  535. throw new JSONException("can not cast to : " + type);
  536. }
  537. @SuppressWarnings({ "unchecked" })
  538. public static final <T> T castToJavaBean(Map<String, Object> map, Class<T> clazz, ParserConfig mapping) {
  539. try {
  540. if (clazz == StackTraceElement.class) {
  541. String declaringClass = (String) map.get("className");
  542. String methodName = (String) map.get("methodName");
  543. String fileName = (String) map.get("fileName");
  544. int lineNumber;
  545. {
  546. Number value = (Number) map.get("lineNumber");
  547. if (value == null) {
  548. lineNumber = 0;
  549. } else {
  550. lineNumber = value.intValue();
  551. }
  552. }
  553. return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber);
  554. }
  555. {
  556. Object iClassObject = map.get("@type");
  557. if (iClassObject instanceof String) {
  558. String className = (String) iClassObject;
  559. clazz = (Class<T>) loadClass(className);
  560. }
  561. }
  562. if (clazz.isInterface()) {
  563. JSONObject object;
  564. if (map instanceof JSONObject) {
  565. object = (JSONObject) map;
  566. } else {
  567. object = new JSONObject(map);
  568. }
  569. return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
  570. new Class<?>[] { clazz }, object);
  571. }
  572. Map<String, FieldDeserializer> setters = mapping.getFieldDeserializers(clazz);
  573. T object = clazz.newInstance();
  574. for (Map.Entry<String, FieldDeserializer> entry : setters.entrySet()) {
  575. String key = entry.getKey();
  576. Method method = entry.getValue().getMethod();
  577. if (map.containsKey(key)) {
  578. Object value = map.get(key);
  579. value = cast(value, method.getGenericParameterTypes()[0], mapping);
  580. method.invoke(object, new Object[] { value });
  581. }
  582. }
  583. return object;
  584. } catch (Exception e) {
  585. throw new JSONException(e.getMessage(), e);
  586. }
  587. }
  588. private static ConcurrentMap<String, Class<?>> mappings = new ConcurrentHashMap<String, Class<?>>();
  589. static {
  590. addBaseClassMappings();
  591. }
  592. public static void addClassMapping(String className, Class<?> clazz) {
  593. if (className == null) {
  594. className = clazz.getName();
  595. }
  596. mappings.put(className, clazz);
  597. }
  598. public static void addBaseClassMappings() {
  599. mappings.put("byte", byte.class);
  600. mappings.put("short", short.class);
  601. mappings.put("int", int.class);
  602. mappings.put("long", long.class);
  603. mappings.put("float", float.class);
  604. mappings.put("double", double.class);
  605. mappings.put("boolean", boolean.class);
  606. mappings.put("char", char.class);
  607. mappings.put("[byte", byte[].class);
  608. mappings.put("[short", short[].class);
  609. mappings.put("[int", int[].class);
  610. mappings.put("[long", long[].class);
  611. mappings.put("[float", float[].class);
  612. mappings.put("[double", double[].class);
  613. mappings.put("[boolean", boolean[].class);
  614. mappings.put("[char", char[].class);
  615. mappings.put(HashMap.class.getName(), HashMap.class);
  616. }
  617. public static void clearClassMapping() {
  618. mappings.clear();
  619. addBaseClassMappings();
  620. }
  621. public static Class<?> loadClass(String className) {
  622. if (className == null || className.length() == 0) {
  623. return null;
  624. }
  625. Class<?> clazz = mappings.get(className);
  626. if (clazz != null) {
  627. return clazz;
  628. }
  629. if (className.charAt(0) == '[') {
  630. Class<?> componentType = loadClass(className.substring(1));
  631. return Array.newInstance(componentType, 0).getClass();
  632. }
  633. if (className.startsWith("L") && className.endsWith(";")) {
  634. String newClassName = className.substring(1, className.length() - 1);
  635. return loadClass(newClassName);
  636. }
  637. try {
  638. clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
  639. addClassMapping(className, clazz);
  640. return clazz;
  641. } catch (Throwable e) {
  642. // skip
  643. }
  644. try {
  645. clazz = Class.forName(className);
  646. addClassMapping(className, clazz);
  647. return clazz;
  648. } catch (Throwable e) {
  649. // skip
  650. }
  651. return clazz;
  652. }
  653. public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String, String> aliasMap) {
  654. return computeGetters(clazz, aliasMap, true);
  655. }
  656. public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String, String> aliasMap, boolean sorted) {
  657. Map<String, FieldInfo> fieldInfoMap = new LinkedHashMap<String, FieldInfo>();
  658. for (Method method : clazz.getMethods()) {
  659. String methodName = method.getName();
  660. if (Modifier.isStatic(method.getModifiers())) {
  661. continue;
  662. }
  663. if (method.getReturnType().equals(Void.TYPE)) {
  664. continue;
  665. }
  666. if (method.getParameterTypes().length != 0) {
  667. continue;
  668. }
  669. if (method.getReturnType() == ClassLoader.class) {
  670. continue;
  671. }
  672. if (method.getName().equals("getMetaClass")
  673. && method.getReturnType().getName().equals("groovy.lang.MetaClass")) {
  674. continue;
  675. }
  676. JSONField annotation = method.getAnnotation(JSONField.class);
  677. if (annotation != null) {
  678. if (!annotation.serialize()) {
  679. continue;
  680. }
  681. if (annotation.name().length() != 0) {
  682. String propertyName = annotation.name();
  683. if (aliasMap != null) {
  684. propertyName = aliasMap.get(propertyName);
  685. if (propertyName == null) {
  686. continue;
  687. }
  688. }
  689. fieldInfoMap.put(propertyName, new FieldInfo(propertyName, method, null));
  690. continue;
  691. }
  692. }
  693. if (methodName.startsWith("get")) {
  694. if (methodName.length() < 4) {
  695. continue;
  696. }
  697. if (methodName.equals("getClass")) {
  698. continue;
  699. }
  700. if (!Character.isUpperCase(methodName.charAt(3))) {
  701. continue;
  702. }
  703. String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
  704. boolean ignore = isJSONTypeIgnore(clazz, propertyName);
  705. if (ignore) {
  706. continue;
  707. }
  708. Field field = ParserConfig.getField(clazz, propertyName);
  709. if (field != null) {
  710. JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
  711. if (fieldAnnotation != null && fieldAnnotation.name().length() != 0) {
  712. propertyName = fieldAnnotation.name();
  713. if (aliasMap != null) {
  714. propertyName = aliasMap.get(propertyName);
  715. if (propertyName == null) {
  716. continue;
  717. }
  718. }
  719. }
  720. }
  721. if (aliasMap != null) {
  722. propertyName = aliasMap.get(propertyName);
  723. if (propertyName == null) {
  724. continue;
  725. }
  726. }
  727. fieldInfoMap.put(propertyName, new FieldInfo(propertyName, method, field));
  728. }
  729. if (methodName.startsWith("is")) {
  730. if (methodName.length() < 3) {
  731. continue;
  732. }
  733. if (!Character.isUpperCase(methodName.charAt(2))) {
  734. continue;
  735. }
  736. String propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3);
  737. Field field = ParserConfig.getField(clazz, propertyName);
  738. if (field != null) {
  739. JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
  740. if (fieldAnnotation != null && fieldAnnotation.name().length() != 0) {
  741. propertyName = fieldAnnotation.name();
  742. if (aliasMap != null) {
  743. propertyName = aliasMap.get(propertyName);
  744. if (propertyName == null) {
  745. continue;
  746. }
  747. }
  748. }
  749. }
  750. if (aliasMap != null) {
  751. propertyName = aliasMap.get(propertyName);
  752. if (propertyName == null) {
  753. continue;
  754. }
  755. }
  756. fieldInfoMap.put(propertyName, new FieldInfo(propertyName, method, field));
  757. }
  758. }
  759. for (Field field : clazz.getFields()) {
  760. if (Modifier.isStatic(field.getModifiers())) {
  761. continue;
  762. }
  763. if (!Modifier.isPublic(field.getModifiers())) {
  764. continue;
  765. }
  766. if (!fieldInfoMap.containsKey(field.getName())) {
  767. fieldInfoMap.put(field.getName(), new FieldInfo(field.getName(), null, field));
  768. }
  769. }
  770. List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
  771. boolean containsAll = false;
  772. String[] orders = null;
  773. JSONType annotation = clazz.getAnnotation(JSONType.class);
  774. if (annotation != null) {
  775. orders = annotation.orders();
  776. if (orders != null && orders.length == fieldInfoMap.size()) {
  777. containsAll = true;
  778. for (String item : orders) {
  779. if (!fieldInfoMap.containsKey(item)) {
  780. containsAll = false;
  781. break;
  782. }
  783. }
  784. } else {
  785. containsAll = false;
  786. }
  787. }
  788. if (containsAll) {
  789. for (String item : orders) {
  790. FieldInfo fieldInfo = fieldInfoMap.get(item);
  791. fieldInfoList.add(fieldInfo);
  792. }
  793. } else {
  794. for (FieldInfo fieldInfo : fieldInfoMap.values()) {
  795. fieldInfoList.add(fieldInfo);
  796. }
  797. if (sorted) {
  798. Collections.sort(fieldInfoList);
  799. }
  800. }
  801. return fieldInfoList;
  802. }
  803. private static boolean isJSONTypeIgnore(Class<?> clazz, String propertyName) {
  804. JSONType jsonType = clazz.getAnnotation(JSONType.class);
  805. if (jsonType != null && jsonType.ignores() != null) {
  806. for (String item : jsonType.ignores()) {
  807. if (propertyName.equalsIgnoreCase(item)) {
  808. return true;
  809. }
  810. }
  811. }
  812. if (clazz.getSuperclass() != Object.class && clazz.getSuperclass() != null) {
  813. if (isJSONTypeIgnore(clazz.getSuperclass(), propertyName)) {
  814. return true;
  815. }
  816. }
  817. return false;
  818. }
  819. public static Class<?> getClass(Type type) {
  820. if (type.getClass() == Class.class) {
  821. return (Class<?>) type;
  822. }
  823. if (type instanceof ParameterizedType) {
  824. return getClass(((ParameterizedType) type).getRawType());
  825. }
  826. return Object.class;
  827. }
  828. }