PageRenderTime 23ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/xiejuntao/xdesktop
Java | 163 lines | 135 code | 26 blank | 2 comment | 64 complexity | ee3115775afeed38d3f1a08211f316a3 MD5 | raw file
  1. package com.alibaba.fastjson.parser.deserializer;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Type;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import com.alibaba.fastjson.JSONException;
  7. import com.alibaba.fastjson.parser.DefaultJSONParser;
  8. import com.alibaba.fastjson.parser.Feature;
  9. import com.alibaba.fastjson.parser.JSONScanner;
  10. import com.alibaba.fastjson.parser.JSONToken;
  11. import com.alibaba.fastjson.parser.ParserConfig;
  12. import com.alibaba.fastjson.util.TypeUtils;
  13. public class ThrowableDeserializer extends JavaBeanDeserializer {
  14. public ThrowableDeserializer(ParserConfig mapping, Class<?> clazz){
  15. super(mapping, clazz);
  16. }
  17. @SuppressWarnings("unchecked")
  18. public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
  19. JSONScanner lexer = (JSONScanner) parser.getLexer();
  20. if (parser.getResolveStatus() == DefaultJSONParser.TypeNameRedirect) {
  21. parser.setResolveStatus(DefaultJSONParser.NONE);
  22. } else {
  23. if (lexer.token() != JSONToken.LBRACE) {
  24. throw new JSONException("syntax error");
  25. }
  26. }
  27. Throwable cause = null;
  28. Class<?> exClass = null;
  29. if (type != null && type instanceof Class) {
  30. Class<?> clazz = (Class<?>) type;
  31. if (Throwable.class.isAssignableFrom(clazz)) {
  32. exClass = clazz;
  33. }
  34. }
  35. String message = null;
  36. StackTraceElement[] stackTrace = null;
  37. Map<String, Object> otherValues = new HashMap<String, Object>();
  38. for (;;) {
  39. // lexer.scanSymbol
  40. String key = lexer.scanSymbol(parser.getSymbolTable());
  41. if (key == null) {
  42. if (lexer.token() == JSONToken.RBRACE) {
  43. lexer.nextToken(JSONToken.COMMA);
  44. break;
  45. }
  46. if (lexer.token() == JSONToken.COMMA) {
  47. if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
  48. continue;
  49. }
  50. }
  51. }
  52. lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
  53. if ("@type".equals(key)) {
  54. if (lexer.token() == JSONToken.LITERAL_STRING) {
  55. String exClassName = lexer.stringVal();
  56. exClass = TypeUtils.loadClass(exClassName);
  57. } else {
  58. throw new JSONException("syntax error");
  59. }
  60. lexer.nextToken(JSONToken.COMMA);
  61. } else if ("message".equals(key)) {
  62. if (lexer.token() == JSONToken.NULL) {
  63. message = null;
  64. } else if (lexer.token() == JSONToken.LITERAL_STRING) {
  65. message = lexer.stringVal();
  66. } else {
  67. throw new JSONException("syntax error");
  68. }
  69. lexer.nextToken();
  70. } else if ("cause".equals(key)) {
  71. cause = deserialze(parser, null, "cause");
  72. } else if ("stackTrace".equals(key)) {
  73. stackTrace = parser.parseObject(StackTraceElement[].class);
  74. } else {
  75. // TODO
  76. otherValues.put(key, parser.parse());
  77. }
  78. if (lexer.token() == JSONToken.COMMA) {
  79. continue;
  80. }
  81. if (lexer.token() == JSONToken.RBRACE) {
  82. lexer.nextToken(JSONToken.COMMA);
  83. break;
  84. }
  85. }
  86. Throwable ex = null;
  87. if (exClass == null) {
  88. ex = new Exception(message, cause);
  89. } else {
  90. try {
  91. ex = createException(message, cause, exClass);
  92. if (ex == null) {
  93. ex = new Exception(message, cause);
  94. }
  95. } catch (Exception e) {
  96. throw new JSONException("create instance error", e);
  97. }
  98. }
  99. if (stackTrace != null) {
  100. ex.setStackTrace(stackTrace);
  101. }
  102. return (T) ex;
  103. }
  104. private Throwable createException(String message, Throwable cause, Class<?> exClass) throws Exception {
  105. Constructor<?> defaultConstructor = null;
  106. Constructor<?> messageConstructor = null;
  107. Constructor<?> causeConstructor = null;
  108. for (Constructor<?> constructor : exClass.getConstructors()) {
  109. if (constructor.getParameterTypes().length == 0) {
  110. defaultConstructor = constructor;
  111. continue;
  112. }
  113. if (constructor.getParameterTypes().length == 1 && constructor.getParameterTypes()[0] == String.class) {
  114. messageConstructor = constructor;
  115. continue;
  116. }
  117. if (constructor.getParameterTypes().length == 2 && constructor.getParameterTypes()[0] == String.class
  118. && constructor.getParameterTypes()[1] == Throwable.class) {
  119. causeConstructor = constructor;
  120. continue;
  121. }
  122. }
  123. if (causeConstructor != null) {
  124. return (Throwable) causeConstructor.newInstance(message, cause);
  125. }
  126. if (messageConstructor != null) {
  127. return (Throwable) messageConstructor.newInstance(message);
  128. }
  129. if (defaultConstructor != null) {
  130. return (Throwable) defaultConstructor.newInstance();
  131. }
  132. return null;
  133. }
  134. public int getFastMatchToken() {
  135. return JSONToken.LBRACE;
  136. }
  137. }