Search in sources :

Example 6 with ObjectDeserializer

use of com.alibaba.fastjson.parser.deserializer.ObjectDeserializer in project uavstack by uavorg.

the class DefaultJSONParser method parseObject.

@SuppressWarnings({ "unchecked", "rawtypes" })
public final Object parseObject(final Map object, Object fieldName) {
    final JSONLexer lexer = this.lexer;
    if (lexer.token() == JSONToken.NULL) {
        lexer.next();
        return null;
    }
    if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
        throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
    }
    ParseContext context = this.getContext();
    try {
        boolean setContextFlag = false;
        for (; ; ) {
            lexer.skipWhitespace();
            char ch = lexer.getCurrent();
            if (isEnabled(Feature.AllowArbitraryCommas)) {
                while (ch == ',') {
                    lexer.next();
                    lexer.skipWhitespace();
                    ch = lexer.getCurrent();
                }
            }
            boolean isObjectKey = false;
            Object key;
            if (ch == '"') {
                key = lexer.scanSymbol(symbolTable, '"');
                lexer.skipWhitespace();
                ch = lexer.getCurrent();
                if (ch != ':') {
                    throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key);
                }
            } else if (ch == '}') {
                lexer.next();
                lexer.resetStringPosition();
                lexer.nextToken();
                return object;
            } else if (ch == '\'') {
                if (!isEnabled(Feature.AllowSingleQuotes)) {
                    throw new JSONException("syntax error");
                }
                key = lexer.scanSymbol(symbolTable, '\'');
                lexer.skipWhitespace();
                ch = lexer.getCurrent();
                if (ch != ':') {
                    throw new JSONException("expect ':' at " + lexer.pos());
                }
            } else if (ch == EOI) {
                throw new JSONException("syntax error");
            } else if (ch == ',') {
                throw new JSONException("syntax error");
            } else if ((ch >= '0' && ch <= '9') || ch == '-') {
                lexer.resetStringPosition();
                lexer.scanNumber();
                if (lexer.token() == JSONToken.LITERAL_INT) {
                    key = lexer.integerValue();
                } else {
                    key = lexer.decimalValue(true);
                }
                ch = lexer.getCurrent();
                if (ch != ':') {
                    throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key);
                }
            } else if (ch == '{' || ch == '[') {
                lexer.nextToken();
                key = parse();
                isObjectKey = true;
            } else {
                if (!isEnabled(Feature.AllowUnQuotedFieldNames)) {
                    throw new JSONException("syntax error");
                }
                key = lexer.scanSymbolUnQuoted(symbolTable);
                lexer.skipWhitespace();
                ch = lexer.getCurrent();
                if (ch != ':') {
                    throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
                }
            }
            if (!isObjectKey) {
                lexer.next();
                lexer.skipWhitespace();
            }
            ch = lexer.getCurrent();
            lexer.resetStringPosition();
            if (key == JSON.DEFAULT_TYPE_KEY && !isEnabled(Feature.DisableSpecialKeyDetect)) {
                String typeName = lexer.scanSymbol(symbolTable, '"');
                Class<?> clazz = TypeUtils.loadClass(typeName);
                if (clazz == null) {
                    object.put(JSON.DEFAULT_TYPE_KEY, typeName);
                    continue;
                }
                lexer.nextToken(JSONToken.COMMA);
                if (lexer.token() == JSONToken.RBRACE) {
                    lexer.nextToken(JSONToken.COMMA);
                    try {
                        Object instance = null;
                        ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
                        if (deserializer instanceof ASMJavaBeanDeserializer) {
                            instance = ((ASMJavaBeanDeserializer) deserializer).createInstance(this, clazz);
                        } else if (deserializer instanceof JavaBeanDeserializer) {
                            instance = ((JavaBeanDeserializer) deserializer).createInstance(this, clazz);
                        }
                        if (instance == null) {
                            if (clazz == Cloneable.class) {
                                instance = new HashMap();
                            } else {
                                instance = clazz.newInstance();
                            }
                        }
                        return instance;
                    } catch (Exception e) {
                        throw new JSONException("create instance error", e);
                    }
                }
                this.setResolveStatus(TypeNameRedirect);
                if (this.context != null && !(fieldName instanceof Integer)) {
                    this.popContext();
                }
                ObjectDeserializer deserializer = config.getDeserializer(clazz);
                return deserializer.deserialze(this, clazz, fieldName);
            }
            if (key == "$ref" && !isEnabled(Feature.DisableSpecialKeyDetect)) {
                lexer.nextToken(JSONToken.LITERAL_STRING);
                if (lexer.token() == JSONToken.LITERAL_STRING) {
                    String ref = lexer.stringVal();
                    lexer.nextToken(JSONToken.RBRACE);
                    Object refValue = null;
                    if ("@".equals(ref)) {
                        if (this.getContext() != null) {
                            ParseContext thisContext = this.getContext();
                            Object thisObj = thisContext.getObject();
                            if (thisObj instanceof Object[] || thisObj instanceof Collection<?>) {
                                refValue = thisObj;
                            } else if (thisContext.getParentContext() != null) {
                                refValue = thisContext.getParentContext().getObject();
                            }
                        }
                    } else if ("..".equals(ref)) {
                        ParseContext parentContext = context.getParentContext();
                        if (parentContext.getObject() != null) {
                            refValue = parentContext.getObject();
                        } else {
                            addResolveTask(new ResolveTask(parentContext, ref));
                            setResolveStatus(DefaultJSONParser.NeedToResolve);
                        }
                    } else if ("$".equals(ref)) {
                        ParseContext rootContext = context;
                        while (rootContext.getParentContext() != null) {
                            rootContext = rootContext.getParentContext();
                        }
                        if (rootContext.getObject() != null) {
                            refValue = rootContext.getObject();
                        } else {
                            addResolveTask(new ResolveTask(rootContext, ref));
                            setResolveStatus(DefaultJSONParser.NeedToResolve);
                        }
                    } else {
                        addResolveTask(new ResolveTask(context, ref));
                        setResolveStatus(DefaultJSONParser.NeedToResolve);
                    }
                    if (lexer.token() != JSONToken.RBRACE) {
                        throw new JSONException("syntax error");
                    }
                    lexer.nextToken(JSONToken.COMMA);
                    return refValue;
                } else {
                    throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
                }
            }
            if (!setContextFlag) {
                setContext(object, fieldName);
                setContextFlag = true;
            }
            if (object.getClass() == JSONObject.class) {
                key = (key == null) ? "null" : key.toString();
            }
            Object value;
            if (ch == '"') {
                lexer.scanString();
                String strValue = lexer.stringVal();
                value = strValue;
                if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
                    JSONScanner iso8601Lexer = new JSONScanner(strValue);
                    if (iso8601Lexer.scanISO8601DateIfMatch()) {
                        value = iso8601Lexer.getCalendar().getTime();
                    }
                    iso8601Lexer.close();
                }
                object.put(key, value);
            } else if (ch >= '0' && ch <= '9' || ch == '-') {
                lexer.scanNumber();
                if (lexer.token() == JSONToken.LITERAL_INT) {
                    value = lexer.integerValue();
                } else {
                    value = lexer.decimalValue(isEnabled(Feature.UseBigDecimal));
                }
                object.put(key, value);
            } else if (ch == '[') {
                // 减少嵌套,兼容android
                lexer.nextToken();
                JSONArray list = new JSONArray();
                this.parseArray(list, key);
                value = list;
                object.put(key, value);
                if (lexer.token() == JSONToken.RBRACE) {
                    lexer.nextToken();
                    return object;
                } else if (lexer.token() == JSONToken.COMMA) {
                    continue;
                } else {
                    throw new JSONException("syntax error");
                }
            } else if (ch == '{') {
                // 减少嵌套,兼容android
                lexer.nextToken();
                final boolean parentIsArray = fieldName != null && fieldName.getClass() == Integer.class;
                JSONObject input = new JSONObject(isEnabled(Feature.OrderedField));
                ParseContext ctxLocal = null;
                if (!parentIsArray) {
                    ctxLocal = setContext(context, input, key);
                }
                Object obj = this.parseObject(input, key);
                if (ctxLocal != null && input != obj) {
                    ctxLocal.setObject(object);
                }
                checkMapResolve(object, key.toString());
                if (object.getClass() == JSONObject.class) {
                    object.put(key.toString(), obj);
                } else {
                    object.put(key, obj);
                }
                if (parentIsArray) {
                    setContext(context, obj, key);
                }
                if (lexer.token() == JSONToken.RBRACE) {
                    lexer.nextToken();
                    setContext(context);
                    return object;
                } else if (lexer.token() == JSONToken.COMMA) {
                    continue;
                } else {
                    throw new JSONException("syntax error, " + lexer.tokenName());
                }
            } else {
                lexer.nextToken();
                value = parse();
                if (object.getClass() == JSONObject.class) {
                    key = key.toString();
                }
                object.put(key, value);
                if (lexer.token() == JSONToken.RBRACE) {
                    lexer.nextToken();
                    return object;
                } else if (lexer.token() == JSONToken.COMMA) {
                    continue;
                } else {
                    throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key);
                }
            }
            lexer.skipWhitespace();
            ch = lexer.getCurrent();
            if (ch == ',') {
                lexer.next();
                continue;
            } else if (ch == '}') {
                lexer.next();
                lexer.resetStringPosition();
                lexer.nextToken();
                this.setContext(object, fieldName);
                return object;
            } else {
                throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key);
            }
        }
    } finally {
        this.setContext(context);
    }
}
Also used : HashMap(java.util.HashMap) JSONArray(com.alibaba.fastjson.JSONArray) JSONException(com.alibaba.fastjson.JSONException) JSONException(com.alibaba.fastjson.JSONException) ASMJavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer) BigInteger(java.math.BigInteger) JSONObject(com.alibaba.fastjson.JSONObject) JSONObject(com.alibaba.fastjson.JSONObject) ObjectDeserializer(com.alibaba.fastjson.parser.deserializer.ObjectDeserializer) ASMJavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer) JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer)

Example 7 with ObjectDeserializer

use of com.alibaba.fastjson.parser.deserializer.ObjectDeserializer in project uavstack by uavorg.

the class ParserConfig method getDeserializer.

public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
    ObjectDeserializer derializer = derializers.get(type);
    if (derializer != null) {
        return derializer;
    }
    if (type == null) {
        type = clazz;
    }
    derializer = derializers.get(type);
    if (derializer != null) {
        return derializer;
    }
    {
        JSONType annotation = clazz.getAnnotation(JSONType.class);
        if (annotation != null) {
            Class<?> mappingTo = annotation.mappingTo();
            if (mappingTo != Void.class) {
                return getDeserializer(mappingTo, mappingTo);
            }
        }
    }
    if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
        derializer = derializers.get(clazz);
    }
    if (derializer != null) {
        return derializer;
    }
    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    try {
        for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) {
            for (Type forType : autowired.getAutowiredFor()) {
                derializers.put(forType, autowired);
            }
        }
    } catch (Exception ex) {
    // skip
    }
    derializer = derializers.get(type);
    if (derializer != null) {
        return derializer;
    }
    if (clazz.isEnum()) {
        derializer = new EnumDeserializer(clazz);
    } else if (clazz.isArray()) {
        derializer = ArrayDeserializer.instance;
    } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) {
        derializer = CollectionDeserializer.instance;
    } else if (Collection.class.isAssignableFrom(clazz)) {
        derializer = CollectionDeserializer.instance;
    } else if (Map.class.isAssignableFrom(clazz)) {
        derializer = MapDeserializer.instance;
    } else if (Throwable.class.isAssignableFrom(clazz)) {
        derializer = new ThrowableDeserializer(this, clazz);
    } else {
        derializer = createJavaBeanDeserializer(clazz, type);
    }
    putDeserializer(type, derializer);
    return derializer;
}
Also used : ThrowableDeserializer(com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer) ArrayList(java.util.ArrayList) JSONException(com.alibaba.fastjson.JSONException) ASMException(com.alibaba.fastjson.asm.ASMException) AccessControlException(java.security.AccessControlException) ParameterizedType(java.lang.reflect.ParameterizedType) EnumDeserializer(com.alibaba.fastjson.parser.deserializer.EnumDeserializer) WildcardType(java.lang.reflect.WildcardType) WildcardType(java.lang.reflect.WildcardType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) JSONType(com.alibaba.fastjson.annotation.JSONType) AutowiredObjectDeserializer(com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer) TypeVariable(java.lang.reflect.TypeVariable) Collection(java.util.Collection) JSONType(com.alibaba.fastjson.annotation.JSONType) JSONObjectDeserializer(com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer) AutowiredObjectDeserializer(com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer) JavaObjectDeserializer(com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer) ObjectDeserializer(com.alibaba.fastjson.parser.deserializer.ObjectDeserializer)

Example 8 with ObjectDeserializer

use of com.alibaba.fastjson.parser.deserializer.ObjectDeserializer in project fastjson by alibaba.

the class TypeUtils method castToEnum.

@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> T castToEnum(Object obj, Class<T> clazz, ParserConfig mapping) {
    try {
        if (obj instanceof String) {
            String name = (String) obj;
            if (name.length() == 0) {
                return null;
            }
            if (mapping == null) {
                mapping = ParserConfig.getGlobalInstance();
            }
            ObjectDeserializer deserializer = mapping.getDeserializer(clazz);
            if (deserializer instanceof EnumDeserializer) {
                EnumDeserializer enumDeserializer = (EnumDeserializer) deserializer;
                return (T) enumDeserializer.getEnumByHashCode(TypeUtils.fnv1a_64(name));
            }
            return (T) Enum.valueOf((Class<? extends Enum>) clazz, name);
        }
        if (obj instanceof BigDecimal) {
            int ordinal = intValue((BigDecimal) obj);
            Object[] values = clazz.getEnumConstants();
            if (ordinal < values.length) {
                return (T) values[ordinal];
            }
        }
        if (obj instanceof Number) {
            int ordinal = ((Number) obj).intValue();
            Object[] values = clazz.getEnumConstants();
            if (ordinal < values.length) {
                return (T) values[ordinal];
            }
        }
    } catch (Exception ex) {
        throw new JSONException("can not cast to : " + clazz.getName(), ex);
    }
    throw new JSONException("can not cast to : " + clazz.getName());
}
Also used : JSONException(com.alibaba.fastjson.JSONException) BigDecimal(java.math.BigDecimal) ParseException(java.text.ParseException) JSONException(com.alibaba.fastjson.JSONException) AccessControlException(java.security.AccessControlException) EnumDeserializer(com.alibaba.fastjson.parser.deserializer.EnumDeserializer) JSONObject(com.alibaba.fastjson.JSONObject) ObjectDeserializer(com.alibaba.fastjson.parser.deserializer.ObjectDeserializer)

Example 9 with ObjectDeserializer

use of com.alibaba.fastjson.parser.deserializer.ObjectDeserializer in project fastjson by alibaba.

the class TypeUtils method castToJavaBean.

@SuppressWarnings({ "unchecked" })
public static <T> T castToJavaBean(Map<String, Object> map, Class<T> clazz, ParserConfig config) {
    try {
        if (clazz == StackTraceElement.class) {
            String declaringClass = (String) map.get("className");
            String methodName = (String) map.get("methodName");
            String fileName = (String) map.get("fileName");
            int lineNumber;
            {
                Number value = (Number) map.get("lineNumber");
                if (value == null) {
                    lineNumber = 0;
                } else if (value instanceof BigDecimal) {
                    lineNumber = ((BigDecimal) value).intValueExact();
                } else {
                    lineNumber = value.intValue();
                }
            }
            return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber);
        }
        {
            Object iClassObject = map.get(JSON.DEFAULT_TYPE_KEY);
            if (iClassObject instanceof String) {
                String className = (String) iClassObject;
                Class<?> loadClazz;
                if (config == null) {
                    config = ParserConfig.global;
                }
                loadClazz = config.checkAutoType(className, null);
                if (loadClazz == null) {
                    throw new ClassNotFoundException(className + " not found");
                }
                if (!loadClazz.equals(clazz)) {
                    return (T) castToJavaBean(map, loadClazz, config);
                }
            }
        }
        if (clazz.isInterface()) {
            JSONObject object;
            if (map instanceof JSONObject) {
                object = (JSONObject) map;
            } else {
                object = new JSONObject(map);
            }
            if (config == null) {
                config = ParserConfig.getGlobalInstance();
            }
            ObjectDeserializer deserializer = config.get(clazz);
            if (deserializer != null) {
                String json = JSON.toJSONString(object);
                return JSON.parseObject(json, clazz);
            }
            return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { clazz }, object);
        }
        if (clazz == Locale.class) {
            Object arg0 = map.get("language");
            Object arg1 = map.get("country");
            if (arg0 instanceof String) {
                String language = (String) arg0;
                if (arg1 instanceof String) {
                    String country = (String) arg1;
                    return (T) new Locale(language, country);
                } else if (arg1 == null) {
                    return (T) new Locale(language);
                }
            }
        }
        if (clazz == String.class && map instanceof JSONObject) {
            return (T) map.toString();
        }
        if (clazz == JSON.class && map instanceof JSONObject) {
            return (T) map;
        }
        if (clazz == LinkedHashMap.class && map instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) map;
            Map<String, Object> innerMap = jsonObject.getInnerMap();
            if (innerMap instanceof LinkedHashMap) {
                return (T) innerMap;
            }
        }
        if (clazz.isInstance(map)) {
            return (T) map;
        }
        if (clazz == JSONObject.class) {
            return (T) new JSONObject(map);
        }
        if (config == null) {
            config = ParserConfig.getGlobalInstance();
        }
        JavaBeanDeserializer javaBeanDeser = null;
        ObjectDeserializer deserializer = config.getDeserializer(clazz);
        if (deserializer instanceof JavaBeanDeserializer) {
            javaBeanDeser = (JavaBeanDeserializer) deserializer;
        }
        if (javaBeanDeser == null) {
            throw new JSONException("can not get javaBeanDeserializer. " + clazz.getName());
        }
        return (T) javaBeanDeser.createInstance(map, config);
    } catch (Exception e) {
        throw new JSONException(e.getMessage(), e);
    }
}
Also used : JSONException(com.alibaba.fastjson.JSONException) JSON(com.alibaba.fastjson.JSON) BigDecimal(java.math.BigDecimal) ParseException(java.text.ParseException) JSONException(com.alibaba.fastjson.JSONException) AccessControlException(java.security.AccessControlException) JSONObject(com.alibaba.fastjson.JSONObject) JSONObject(com.alibaba.fastjson.JSONObject) ObjectDeserializer(com.alibaba.fastjson.parser.deserializer.ObjectDeserializer) JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer)

Example 10 with ObjectDeserializer

use of com.alibaba.fastjson.parser.deserializer.ObjectDeserializer in project fastjson by alibaba.

the class Issue3329 method test_for_issue.

public void test_for_issue() throws Exception {
    ParserConfig config = new ParserConfig();
    IdentityHashMap<Type, ObjectDeserializer> deserializers = config.getDeserializers();
    int initSize = deserializers.size();
    for (int i = 0; i < 1000 * 10; ++i) {
        assertEquals(123, ((VO<User>) JSON.parseObject("{\"value\":{\"id\":123}}", new ParameterizedTypeImpl(new Type[] { User.class }, null, VO.class), config)).value.id);
    }
    assertEquals(2, deserializers.size() - initSize);
}
Also used : Type(java.lang.reflect.Type) ParameterizedTypeImpl(com.alibaba.fastjson.util.ParameterizedTypeImpl) ParserConfig(com.alibaba.fastjson.parser.ParserConfig) ObjectDeserializer(com.alibaba.fastjson.parser.deserializer.ObjectDeserializer)

Aggregations

ObjectDeserializer (com.alibaba.fastjson.parser.deserializer.ObjectDeserializer)27 JSONObject (com.alibaba.fastjson.JSONObject)12 JSONException (com.alibaba.fastjson.JSONException)10 JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer)10 Type (java.lang.reflect.Type)9 FieldDeserializer (com.alibaba.fastjson.parser.deserializer.FieldDeserializer)8 HashMap (java.util.HashMap)7 Map (java.util.Map)7 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)7 ConcurrentMap (java.util.concurrent.ConcurrentMap)7 DefaultJSONParser (com.alibaba.fastjson.parser.DefaultJSONParser)5 ParameterizedType (java.lang.reflect.ParameterizedType)4 WildcardType (java.lang.reflect.WildcardType)4 BigInteger (java.math.BigInteger)4 AccessControlException (java.security.AccessControlException)4 ArrayList (java.util.ArrayList)4 IdentityHashMap (java.util.IdentityHashMap)4 ParserConfig (com.alibaba.fastjson.parser.ParserConfig)3 ParseException (java.text.ParseException)3 List (java.util.List)3