package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; public class StackTraceElementDeserializer implements ObjectDeserializer { public final static StackTraceElementDeserializer instance = new StackTraceElementDeserializer(); @SuppressWarnings("unchecked") public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.NULL) { lexer.nextToken(); return null; } if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { throw new JSONException("syntax error: " + JSONToken.name(lexer.token())); } String declaringClass = null; String methodName = null; String fileName = null; int lineNumber = 0; for (;;) { // lexer.scanSymbol String key = lexer.scanSymbol(parser.getSymbolTable()); if (key == null) { if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); break; } if (lexer.token() == JSONToken.COMMA) { if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { continue; } } } lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); if (key == "className") { if (lexer.token() == JSONToken.NULL) { declaringClass = null; } else if (lexer.token() == JSONToken.LITERAL_STRING) { declaringClass = lexer.stringVal(); } else { throw new JSONException("syntax error"); } } else if (key == "methodName") { if (lexer.token() == JSONToken.NULL) { methodName = null; } else if (lexer.token() == JSONToken.LITERAL_STRING) { methodName = lexer.stringVal(); } else { throw new JSONException("syntax error"); } } else if (key == "fileName") { if (lexer.token() == JSONToken.NULL) { fileName = null; } else if (lexer.token() == JSONToken.LITERAL_STRING) { fileName = lexer.stringVal(); } else { throw new JSONException("syntax error"); } } else if (key == "lineNumber") { if (lexer.token() == JSONToken.NULL) { lineNumber = 0; } else if (lexer.token() == JSONToken.LITERAL_INT) { lineNumber = lexer.intValue(); } else { throw new JSONException("syntax error"); } } else if (key == "nativeMethod") { if (lexer.token() == JSONToken.NULL) { lexer.nextToken(JSONToken.COMMA); } else if (lexer.token() == JSONToken.TRUE) { lexer.nextToken(JSONToken.COMMA); } else if (lexer.token() == JSONToken.FALSE) { lexer.nextToken(JSONToken.COMMA); } else { throw new JSONException("syntax error"); } } else if (key == "@type") { if (lexer.token() == JSONToken.NULL) { // skip } else if (lexer.token() == JSONToken.LITERAL_STRING) { String elementType = lexer.stringVal(); if (!elementType.equals("java.lang.StackTraceElement")) { throw new JSONException("syntax error : " + elementType); } } else { throw new JSONException("syntax error"); } } else { throw new JSONException("syntax error : " + key); } if (lexer.token() == JSONToken.COMMA) { continue; } if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); break; } } return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber); } public int getFastMatchToken() { return JSONToken.LBRACE; } }