Search in sources :

Example 6 with ParseContext

use of com.alibaba.fastjson.parser.ParseContext in project fastjson by alibaba.

the class DefaultFieldDeserializer method parseField.

@Override
public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) {
    if (fieldValueDeserilizer == null) {
        getFieldValueDeserilizer(parser.getConfig());
    }
    Type fieldType = fieldInfo.fieldType;
    if (objectType instanceof ParameterizedType) {
        ParseContext objContext = parser.getContext();
        if (objContext != null) {
            objContext.type = objectType;
        }
        fieldType = FieldInfo.getFieldType(this.clazz, objectType, fieldType);
        fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType);
    }
    // ContextObjectDeserializer
    Object value;
    if (fieldValueDeserilizer instanceof JavaBeanDeserializer && fieldInfo.parserFeatures != 0) {
        JavaBeanDeserializer javaBeanDeser = (JavaBeanDeserializer) fieldValueDeserilizer;
        value = javaBeanDeser.deserialze(parser, fieldType, fieldInfo.name, fieldInfo.parserFeatures);
    } else {
        if (this.fieldInfo.format != null && fieldValueDeserilizer instanceof ContextObjectDeserializer) {
            value = //
            ((ContextObjectDeserializer) fieldValueDeserilizer).deserialze(parser, fieldType, fieldInfo.name, fieldInfo.format, fieldInfo.parserFeatures);
        } else {
            value = fieldValueDeserilizer.deserialze(parser, fieldType, fieldInfo.name);
        }
    }
    if (parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) {
        ResolveTask task = parser.getLastResolveTask();
        task.fieldDeserializer = this;
        task.ownerContext = parser.getContext();
        parser.setResolveStatus(DefaultJSONParser.NONE);
    } else {
        if (object == null) {
            fieldValues.put(fieldInfo.name, value);
        } else {
            setValue(object, value);
        }
    }
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ParseContext(com.alibaba.fastjson.parser.ParseContext) ResolveTask(com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask)

Example 7 with ParseContext

use of com.alibaba.fastjson.parser.ParseContext in project fastjson by alibaba.

the class JavaBeanDeserializer method deserialze.

@SuppressWarnings({ "unchecked", "rawtypes" })
protected <// 
T> // 
T deserialze(// 
DefaultJSONParser parser, // 
Type type, // 
Object fieldName, //
Object object, //
int features, int[] setFlags) {
    if (type == JSON.class || type == JSONObject.class) {
        return (T) parser.parse();
    }
    // xxx
    final JSONLexerBase lexer = (JSONLexerBase) parser.lexer;
    int token = lexer.token();
    if (token == JSONToken.NULL) {
        lexer.nextToken(JSONToken.COMMA);
        return null;
    }
    ParseContext context = parser.getContext();
    if (object != null && context != null) {
        context = context.parent;
    }
    ParseContext childContext = null;
    try {
        Map<String, Object> fieldValues = null;
        if (token == JSONToken.RBRACE) {
            lexer.nextToken(JSONToken.COMMA);
            if (object == null) {
                object = createInstance(parser, type);
            }
            return (T) object;
        }
        if (token == JSONToken.LBRACKET) {
            final int mask = Feature.SupportArrayToBean.mask;
            boolean isSupportArrayToBean = //
            (beanInfo.parserFeatures & mask) != 0 || //
            lexer.isEnabled(Feature.SupportArrayToBean) || (features & mask) != 0;
            if (isSupportArrayToBean) {
                return deserialzeArrayMapping(parser, type, fieldName, object);
            }
        }
        if (token != JSONToken.LBRACE && token != JSONToken.COMMA) {
            if (lexer.isBlankInput()) {
                return null;
            }
            if (token == JSONToken.LITERAL_STRING) {
                String strVal = lexer.stringVal();
                if (strVal.length() == 0) {
                    lexer.nextToken();
                    return null;
                }
            }
            if (token == JSONToken.LBRACKET && lexer.getCurrent() == ']') {
                lexer.next();
                lexer.nextToken();
                return null;
            }
            StringBuffer buf = //
            (new StringBuffer()).append(//
            "syntax error, expect {, actual ").append(//
            lexer.tokenName()).append(//
            ", pos ").append(//
            lexer.pos());
            if (fieldName instanceof String) {
                //
                buf.append(//
                ", fieldName ").append(fieldName);
            }
            throw new JSONException(buf.toString());
        }
        if (parser.resolveStatus == DefaultJSONParser.TypeNameRedirect) {
            parser.resolveStatus = DefaultJSONParser.NONE;
        }
        for (int fieldIndex = 0; ; fieldIndex++) {
            String key = null;
            FieldDeserializer fieldDeser = null;
            FieldInfo fieldInfo = null;
            Class<?> fieldClass = null;
            JSONField feildAnnotation = null;
            if (fieldIndex < sortedFieldDeserializers.length) {
                fieldDeser = sortedFieldDeserializers[fieldIndex];
                fieldInfo = fieldDeser.fieldInfo;
                fieldClass = fieldInfo.fieldClass;
                feildAnnotation = fieldInfo.getAnnotation();
            }
            boolean matchField = false;
            boolean valueParsed = false;
            Object fieldValue = null;
            if (fieldDeser != null) {
                char[] name_chars = fieldInfo.name_chars;
                if (fieldClass == int.class || fieldClass == Integer.class) {
                    fieldValue = lexer.scanFieldInt(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == long.class || fieldClass == Long.class) {
                    fieldValue = lexer.scanFieldLong(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == String.class) {
                    fieldValue = lexer.scanFieldString(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == boolean.class || fieldClass == Boolean.class) {
                    fieldValue = lexer.scanFieldBoolean(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == float.class || fieldClass == Float.class) {
                    fieldValue = lexer.scanFieldFloat(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == double.class || fieldClass == Double.class) {
                    fieldValue = lexer.scanFieldDouble(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (// 
                fieldClass.isEnum() && parser.getConfig().getDeserializer(fieldClass) instanceof EnumDeserializer && (feildAnnotation == null || feildAnnotation.deserializeUsing() == Void.class)) {
                    if (fieldDeser instanceof DefaultFieldDeserializer) {
                        ObjectDeserializer fieldValueDeserilizer = ((DefaultFieldDeserializer) fieldDeser).fieldValueDeserilizer;
                        fieldValue = this.scanEnum(lexer, name_chars, fieldValueDeserilizer);
                        if (lexer.matchStat > 0) {
                            matchField = true;
                            valueParsed = true;
                        } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                            continue;
                        }
                    }
                } else if (fieldClass == int[].class) {
                    fieldValue = lexer.scanFieldIntArray(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == float[].class) {
                    fieldValue = lexer.scanFieldFloatArray(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (fieldClass == float[][].class) {
                    fieldValue = lexer.scanFieldFloatArray2(name_chars);
                    if (lexer.matchStat > 0) {
                        matchField = true;
                        valueParsed = true;
                    } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
                        continue;
                    }
                } else if (lexer.matchField(name_chars)) {
                    matchField = true;
                } else {
                    continue;
                }
            }
            if (!matchField) {
                key = lexer.scanSymbol(parser.symbolTable);
                if (key == null) {
                    token = lexer.token();
                    if (token == JSONToken.RBRACE) {
                        lexer.nextToken(JSONToken.COMMA);
                        break;
                    }
                    if (token == JSONToken.COMMA) {
                        if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
                            continue;
                        }
                    }
                }
                if ("$ref" == key) {
                    lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
                    token = lexer.token();
                    if (token == JSONToken.LITERAL_STRING) {
                        String ref = lexer.stringVal();
                        if ("@".equals(ref)) {
                            object = context.object;
                        } else if ("..".equals(ref)) {
                            ParseContext parentContext = context.parent;
                            if (parentContext.object != null) {
                                object = parentContext.object;
                            } else {
                                parser.addResolveTask(new ResolveTask(parentContext, ref));
                                parser.resolveStatus = DefaultJSONParser.NeedToResolve;
                            }
                        } else if ("$".equals(ref)) {
                            ParseContext rootContext = context;
                            while (rootContext.parent != null) {
                                rootContext = rootContext.parent;
                            }
                            if (rootContext.object != null) {
                                object = rootContext.object;
                            } else {
                                parser.addResolveTask(new ResolveTask(rootContext, ref));
                                parser.resolveStatus = DefaultJSONParser.NeedToResolve;
                            }
                        } else {
                            parser.addResolveTask(new ResolveTask(context, ref));
                            parser.resolveStatus = DefaultJSONParser.NeedToResolve;
                        }
                    } else {
                        throw new JSONException("illegal ref, " + JSONToken.name(token));
                    }
                    lexer.nextToken(JSONToken.RBRACE);
                    if (lexer.token() != JSONToken.RBRACE) {
                        throw new JSONException("illegal ref");
                    }
                    lexer.nextToken(JSONToken.COMMA);
                    parser.setContext(context, object, fieldName);
                    return (T) object;
                }
                if (JSON.DEFAULT_TYPE_KEY == key) {
                    lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
                    if (lexer.token() == JSONToken.LITERAL_STRING) {
                        String typeName = lexer.stringVal();
                        lexer.nextToken(JSONToken.COMMA);
                        if (typeName.equals(beanInfo.typeName) || parser.isEnabled(Feature.IgnoreAutoType)) {
                            if (lexer.token() == JSONToken.RBRACE) {
                                lexer.nextToken();
                                break;
                            }
                            continue;
                        }
                        ParserConfig config = parser.getConfig();
                        ObjectDeserializer deserializer = getSeeAlso(config, this.beanInfo, typeName);
                        Class<?> userType = null;
                        if (deserializer == null) {
                            Class<?> expectClass = TypeUtils.getClass(type);
                            userType = config.checkAutoType(typeName, expectClass);
                            deserializer = parser.getConfig().getDeserializer(userType);
                        }
                        return (T) deserializer.deserialze(parser, userType, fieldName);
                    } else {
                        throw new JSONException("syntax error");
                    }
                }
            }
            if (object == null && fieldValues == null) {
                object = createInstance(parser, type);
                if (object == null) {
                    fieldValues = new HashMap<String, Object>(this.fieldDeserializers.length);
                }
                childContext = parser.setContext(context, object, fieldName);
            }
            if (matchField) {
                if (!valueParsed) {
                    fieldDeser.parseField(parser, object, type, fieldValues);
                } else {
                    if (object == null) {
                        fieldValues.put(fieldInfo.name, fieldValue);
                    } else if (fieldValue == null) {
                        if (//
                        fieldClass != int.class && //
                        fieldClass != long.class && //
                        fieldClass != float.class && //
                        fieldClass != double.class && //
                        fieldClass != boolean.class) {
                            fieldDeser.setValue(object, fieldValue);
                        }
                    } else {
                        fieldDeser.setValue(object, fieldValue);
                    }
                    if (lexer.matchStat == JSONLexer.END) {
                        break;
                    }
                }
            } else {
                boolean match = parseField(parser, key, object, type, fieldValues, setFlags);
                if (!match) {
                    if (lexer.token() == JSONToken.RBRACE) {
                        lexer.nextToken();
                        break;
                    }
                    continue;
                } else if (lexer.token() == JSONToken.COLON) {
                    throw new JSONException("syntax error, unexpect token ':'");
                }
            }
            if (lexer.token() == JSONToken.COMMA) {
                continue;
            }
            if (lexer.token() == JSONToken.RBRACE) {
                lexer.nextToken(JSONToken.COMMA);
                break;
            }
            if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) {
                throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token()));
            }
        }
        if (object == null) {
            if (fieldValues == null) {
                object = createInstance(parser, type);
                if (childContext == null) {
                    childContext = parser.setContext(context, object, fieldName);
                }
                return (T) object;
            }
            FieldInfo[] fieldInfoList = beanInfo.fields;
            int size = fieldInfoList.length;
            Object[] params = new Object[size];
            for (int i = 0; i < size; ++i) {
                FieldInfo fieldInfo = fieldInfoList[i];
                Object param = fieldValues.get(fieldInfo.name);
                if (param == null) {
                    Type fieldType = fieldInfo.fieldType;
                    if (fieldType == byte.class) {
                        param = (byte) 0;
                    } else if (fieldType == short.class) {
                        param = (short) 0;
                    } else if (fieldType == int.class) {
                        param = 0;
                    } else if (fieldType == long.class) {
                        param = 0L;
                    } else if (fieldType == float.class) {
                        param = 0F;
                    } else if (fieldType == double.class) {
                        param = 0D;
                    } else if (fieldType == boolean.class) {
                        param = Boolean.FALSE;
                    }
                }
                params[i] = param;
            }
            if (beanInfo.creatorConstructor != null) {
                try {
                    object = beanInfo.creatorConstructor.newInstance(params);
                } catch (Exception e) {
                    throw new JSONException("create instance error, " + beanInfo.creatorConstructor.toGenericString(), e);
                }
            } else if (beanInfo.factoryMethod != null) {
                try {
                    object = beanInfo.factoryMethod.invoke(null, params);
                } catch (Exception e) {
                    throw new JSONException("create factory method error, " + beanInfo.factoryMethod.toString(), e);
                }
            }
        }
        Method buildMethod = beanInfo.buildMethod;
        if (buildMethod == null) {
            return (T) object;
        }
        Object builtObj;
        try {
            builtObj = buildMethod.invoke(object);
        } catch (Exception e) {
            throw new JSONException("build object error", e);
        }
        return (T) builtObj;
    } finally {
        if (childContext != null) {
            childContext.object = object;
        }
        parser.setContext(context);
    }
}
Also used : JSONField(com.alibaba.fastjson.annotation.JSONField) JSON(com.alibaba.fastjson.JSON) JSONLexerBase(com.alibaba.fastjson.parser.JSONLexerBase) JSONException(com.alibaba.fastjson.JSONException) JSONException(com.alibaba.fastjson.JSONException) JSONObject(com.alibaba.fastjson.JSONObject) ParseContext(com.alibaba.fastjson.parser.ParseContext) JSONObject(com.alibaba.fastjson.JSONObject) FieldInfo(com.alibaba.fastjson.util.FieldInfo) ParserConfig(com.alibaba.fastjson.parser.ParserConfig) ResolveTask(com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask)

Example 8 with ParseContext

use of com.alibaba.fastjson.parser.ParseContext in project fastjson by alibaba.

the class JavaBeanDeserializer method createInstance.

public Object createInstance(DefaultJSONParser parser, Type type) {
    if (type instanceof Class) {
        if (clazz.isInterface()) {
            Class<?> clazz = (Class<?>) type;
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            final JSONObject obj = new JSONObject();
            Object proxy = Proxy.newProxyInstance(loader, new Class<?>[] { clazz }, obj);
            return proxy;
        }
    }
    if (beanInfo.defaultConstructor == null) {
        return null;
    }
    Object object;
    try {
        Constructor<?> constructor = beanInfo.defaultConstructor;
        if (beanInfo.defaultConstructorParameterSize == 0) {
            object = constructor.newInstance();
        } else {
            ParseContext context = parser.getContext();
            if (context == null || context.object == null) {
                throw new JSONException("can't create non-static inner class instance.");
            }
            String parentName = context.object.getClass().getName();
            String typeName = "";
            if (type instanceof Class) {
                typeName = ((Class<?>) type).getName();
            }
            if (parentName.length() != typeName.lastIndexOf('$') - 1) {
                char[] typeChars = typeName.toCharArray();
                StringBuilder clsNameBuilder = new StringBuilder();
                clsNameBuilder.append(parentName).append("$");
                Map<String, Object> outterCached = new HashMap<String, Object>();
                //outtest
                outterCached.put(parentName, context.object);
                for (int i = parentName.length() + 1; i <= typeName.lastIndexOf('$'); i++) {
                    char thisChar = typeChars[i];
                    if (thisChar == '$') {
                        String clsName = clsNameBuilder.toString();
                        Object outter = outterCached.get(parentName);
                        Class<?> clazz;
                        try {
                            clazz = Class.forName(parentName);
                            if (outter != null) {
                                Class<?> innerCls = Class.forName(clsName);
                                Constructor<?> innerClsConstructor = innerCls.getDeclaredConstructor(clazz);
                                if (!innerClsConstructor.isAccessible()) {
                                    innerClsConstructor.setAccessible(true);
                                }
                                Object inner = innerClsConstructor.newInstance(outter);
                                outterCached.put(clsName, inner);
                                parentName = clsName;
                            }
                        } catch (ClassNotFoundException e) {
                            throw new JSONException("unable to find class " + parentName);
                        } catch (NoSuchMethodException e) {
                            // no default contrutor
                            throw new RuntimeException(e);
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException("can not instantiate " + clsName);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        } catch (InstantiationException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    clsNameBuilder.append(thisChar);
                }
                object = constructor.newInstance(outterCached.get(parentName));
            } else {
                object = constructor.newInstance(context.object);
            }
        }
    } catch (Exception e) {
        throw new JSONException("create instance error, class " + clazz.getName(), e);
    }
    if (// 
    parser != null && parser.lexer.isEnabled(Feature.InitStringFieldAsEmpty)) {
        for (FieldInfo fieldInfo : beanInfo.fields) {
            if (fieldInfo.fieldClass == String.class) {
                try {
                    fieldInfo.set(object, "");
                } catch (Exception e) {
                    throw new JSONException("create instance error, class " + clazz.getName(), e);
                }
            }
        }
    }
    return object;
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) JSONException(com.alibaba.fastjson.JSONException) JSONException(com.alibaba.fastjson.JSONException) JSONObject(com.alibaba.fastjson.JSONObject) ParseContext(com.alibaba.fastjson.parser.ParseContext) JSONObject(com.alibaba.fastjson.JSONObject) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Example 9 with ParseContext

use of com.alibaba.fastjson.parser.ParseContext in project fastjson by alibaba.

the class ASMDeserializerFactory method _deserialze.

private void _deserialze(ClassWriter cw, Context context) {
    if (context.fieldInfoList.length == 0) {
        return;
    }
    for (FieldInfo fieldInfo : context.fieldInfoList) {
        Class<?> fieldClass = fieldInfo.fieldClass;
        Type fieldType = fieldInfo.fieldType;
        if (fieldClass == char.class) {
            return;
        }
        if (Collection.class.isAssignableFrom(fieldClass)) {
            if (fieldType instanceof ParameterizedType) {
                Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
                if (itemType instanceof Class) {
                    continue;
                } else {
                    return;
                }
            } else {
                return;
            }
        }
    }
    JavaBeanInfo beanInfo = context.beanInfo;
    context.fieldInfoList = beanInfo.sortedFields;
    MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "deserialze", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;", null, null);
    Label reset_ = new Label();
    Label super_ = new Label();
    Label return_ = new Label();
    Label end_ = new Label();
    defineVarLexer(context, mw);
    {
        Label next_ = new Label();
        // isSupportArrayToBean
        mw.visitVarInsn(ALOAD, context.var("lexer"));
        mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "token", "()I");
        mw.visitLdcInsn(JSONToken.LBRACKET);
        mw.visitJumpInsn(IF_ICMPNE, next_);
        if ((beanInfo.parserFeatures & Feature.SupportArrayToBean.mask) == 0) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ILOAD, 4);
            mw.visitLdcInsn(Feature.SupportArrayToBean.mask);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(II)Z");
            mw.visitJumpInsn(IFEQ, next_);
        }
        mw.visitVarInsn(ALOAD, 0);
        mw.visitVarInsn(ALOAD, Context.parser);
        mw.visitVarInsn(ALOAD, 2);
        mw.visitVarInsn(ALOAD, 3);
        //mw.visitVarInsn(ALOAD, 5);
        mw.visitInsn(ACONST_NULL);
        //
        mw.visitMethodInsn(//
        INVOKESPECIAL, //
        context.className, //
        "deserialzeArrayMapping", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
        mw.visitInsn(ARETURN);
        mw.visitLabel(next_);
    // deserialzeArrayMapping
    }
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(Feature.SortFeidFastMatch.mask);
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(I)Z");
    mw.visitJumpInsn(IFEQ, super_);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(context.clazz.getName());
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanType", "(Ljava/lang/String;)I");
    mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.NOT_MATCH);
    mw.visitJumpInsn(IF_ICMPEQ, super_);
    // parser
    mw.visitVarInsn(ALOAD, 1);
    mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getContext", "()" + desc(ParseContext.class));
    mw.visitVarInsn(ASTORE, context.var("mark_context"));
    // ParseContext context = parser.getContext();
    mw.visitInsn(ICONST_0);
    mw.visitVarInsn(ISTORE, context.var("matchedCount"));
    _createInstance(context, mw);
    {
        // parser
        mw.visitVarInsn(ALOAD, 1);
        mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getContext", "()" + desc(ParseContext.class));
        mw.visitVarInsn(ASTORE, context.var("context"));
        // parser
        mw.visitVarInsn(ALOAD, 1);
        mw.visitVarInsn(ALOAD, context.var("context"));
        mw.visitVarInsn(ALOAD, context.var("instance"));
        // fieldName
        mw.visitVarInsn(ALOAD, 3);
        //
        mw.visitMethodInsn(//
        INVOKEVIRTUAL, //
        DefaultJSONParser, //
        "setContext", "(" + desc(ParseContext.class) + "Ljava/lang/Object;Ljava/lang/Object;)" + desc(ParseContext.class));
        mw.visitVarInsn(ASTORE, context.var("childContext"));
    }
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
    mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END);
    mw.visitJumpInsn(IF_ICMPEQ, return_);
    // UNKOWN
    mw.visitInsn(ICONST_0);
    mw.visitIntInsn(ISTORE, context.var("matchStat"));
    int fieldListSize = context.fieldInfoList.length;
    for (int i = 0; i < fieldListSize; i += 32) {
        mw.visitInsn(ICONST_0);
        mw.visitVarInsn(ISTORE, context.var("_asm_flag_" + (i / 32)));
    }
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(Feature.InitStringFieldAsEmpty.mask);
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(I)Z");
    mw.visitIntInsn(ISTORE, context.var("initStringFieldAsEmpty"));
    // declare and init
    for (int i = 0; i < fieldListSize; ++i) {
        FieldInfo fieldInfo = context.fieldInfoList[i];
        Class<?> fieldClass = fieldInfo.fieldClass;
        if (//
        fieldClass == boolean.class || //
        fieldClass == byte.class || //
        fieldClass == short.class || fieldClass == int.class) {
            mw.visitInsn(ICONST_0);
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == long.class) {
            mw.visitInsn(LCONST_0);
            mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2));
        } else if (fieldClass == float.class) {
            mw.visitInsn(FCONST_0);
            mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == double.class) {
            mw.visitInsn(DCONST_0);
            mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2));
        } else {
            if (fieldClass == String.class) {
                Label flagEnd_ = new Label();
                Label flagElse_ = new Label();
                mw.visitVarInsn(ILOAD, context.var("initStringFieldAsEmpty"));
                mw.visitJumpInsn(IFEQ, flagElse_);
                _setFlag(mw, context, i);
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "stringDefaultValue", "()Ljava/lang/String;");
                mw.visitJumpInsn(GOTO, flagEnd_);
                mw.visitLabel(flagElse_);
                mw.visitInsn(ACONST_NULL);
                mw.visitLabel(flagEnd_);
            } else {
                mw.visitInsn(ACONST_NULL);
            }
            // cast
            mw.visitTypeInsn(CHECKCAST, type(fieldClass));
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        }
    }
    for (int i = 0; i < fieldListSize; ++i) {
        FieldInfo fieldInfo = context.fieldInfoList[i];
        Class<?> fieldClass = fieldInfo.fieldClass;
        Type fieldType = fieldInfo.fieldType;
        Label notMatch_ = new Label();
        if (fieldClass == boolean.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldBoolean", "([C)Z");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == byte.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == short.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == int.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == long.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldLong", "([C)J");
            mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2));
        } else if (fieldClass == float.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloat", "([C)F");
            mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == double.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldDouble", "([C)D");
            mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2));
        } else if (fieldClass == String.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldString", "([C)Ljava/lang/String;");
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == int[].class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldIntArray", "([C)[I");
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == float[].class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloatArray", "([C)[F");
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == float[][].class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloatArray2", "([C)[[F");
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass.isEnum()) {
            mw.visitVarInsn(ALOAD, 0);
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            _getFieldDeser(context, mw, fieldInfo);
            mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "scanEnum", "(L" + JSONLexerBase + ";[C" + desc(ObjectDeserializer.class) + ")Ljava/lang/Enum;");
            // cast
            mw.visitTypeInsn(CHECKCAST, type(fieldClass));
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        //            } else if (fieldClass.isEnum()) {
        //                mw.visitVarInsn(ALOAD, context.var("lexer"));
        //                mw.visitVarInsn(ALOAD, 0);
        //                mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
        //                Label enumNull_ = new Label();
        //                mw.visitInsn(ACONST_NULL);
        //                mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast
        //                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        //
        //                mw.visitVarInsn(ALOAD, 1);
        //
        //                mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getSymbolTable", "()" + desc(SymbolTable.class));
        //
        //                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldSymbol",
        //                        "([C" + desc(SymbolTable.class) + ")Ljava/lang/String;");
        //                mw.visitInsn(DUP);
        //                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm_enumName"));
        //
        //                mw.visitJumpInsn(IFNULL, enumNull_);
        //
        //                mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName"));
        //                mw.visitMethodInsn(INVOKEVIRTUAL, type(String.class), "length", "()I");
        //                mw.visitJumpInsn(IFEQ, enumNull_);
        //
        //                mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName"));
        //                mw.visitMethodInsn(INVOKESTATIC, type(fieldClass), "valueOf",
        //                        "(Ljava/lang/String;)" + desc(fieldClass));
        //                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        //                mw.visitLabel(enumNull_);
        } else if (Collection.class.isAssignableFrom(fieldClass)) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(ALOAD, 0);
            mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
            Class<?> itemClass = TypeUtils.getCollectionItemClass(fieldType);
            if (itemClass == String.class) {
                // cast
                mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldStringArray", "([CLjava/lang/Class;)" + desc(Collection.class));
                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
            } else {
                _deserialze_list_obj(context, mw, reset_, fieldInfo, fieldClass, itemClass, i);
                if (i == fieldListSize - 1) {
                    _deserialize_endCheck(context, mw, reset_);
                }
                continue;
            }
        } else {
            _deserialze_obj(context, mw, reset_, fieldInfo, fieldClass, i);
            if (i == fieldListSize - 1) {
                _deserialize_endCheck(context, mw, reset_);
            }
            continue;
        }
        mw.visitVarInsn(ALOAD, context.var("lexer"));
        mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
        Label flag_ = new Label();
        // mw.visitInsn(DUP);
        mw.visitJumpInsn(IFLE, flag_);
        _setFlag(mw, context, i);
        mw.visitLabel(flag_);
        mw.visitVarInsn(ALOAD, context.var("lexer"));
        mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
        mw.visitInsn(DUP);
        mw.visitVarInsn(ISTORE, context.var("matchStat"));
        mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.NOT_MATCH);
        mw.visitJumpInsn(IF_ICMPEQ, reset_);
        mw.visitVarInsn(ALOAD, context.var("lexer"));
        mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
        mw.visitJumpInsn(IFLE, notMatch_);
        // increment matchedCount
        mw.visitVarInsn(ILOAD, context.var("matchedCount"));
        mw.visitInsn(ICONST_1);
        mw.visitInsn(IADD);
        mw.visitVarInsn(ISTORE, context.var("matchedCount"));
        mw.visitVarInsn(ALOAD, context.var("lexer"));
        mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
        mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END);
        mw.visitJumpInsn(IF_ICMPEQ, end_);
        mw.visitLabel(notMatch_);
        if (i == fieldListSize - 1) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
            mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END);
            mw.visitJumpInsn(IF_ICMPNE, reset_);
        }
    }
    // endFor
    mw.visitLabel(end_);
    if (!context.clazz.isInterface() && !Modifier.isAbstract(context.clazz.getModifiers())) {
        _batchSet(context, mw);
    }
    mw.visitLabel(return_);
    _setContext(context, mw);
    mw.visitVarInsn(ALOAD, context.var("instance"));
    Method buildMethod = context.beanInfo.buildMethod;
    if (buildMethod != null) {
        mw.visitMethodInsn(INVOKEVIRTUAL, type(context.getInstClass()), buildMethod.getName(), "()" + desc(buildMethod.getReturnType()));
    }
    mw.visitInsn(ARETURN);
    mw.visitLabel(reset_);
    _batchSet(context, mw);
    mw.visitVarInsn(ALOAD, 0);
    mw.visitVarInsn(ALOAD, 1);
    mw.visitVarInsn(ALOAD, 2);
    mw.visitVarInsn(ALOAD, 3);
    mw.visitVarInsn(ALOAD, context.var("instance"));
    mw.visitVarInsn(ILOAD, 4);
    int flagSize = (fieldListSize / 32);
    if (fieldListSize != 0 && (fieldListSize % 32) != 0) {
        flagSize += 1;
    }
    if (flagSize == 1) {
        mw.visitInsn(ICONST_1);
    } else {
        mw.visitIntInsn(BIPUSH, flagSize);
    }
    mw.visitIntInsn(NEWARRAY, T_INT);
    for (int i = 0; i < flagSize; ++i) {
        mw.visitInsn(DUP);
        if (i == 0) {
            mw.visitInsn(ICONST_0);
        } else if (i == 1) {
            mw.visitInsn(ICONST_1);
        } else {
            mw.visitIntInsn(BIPUSH, i);
        }
        mw.visitVarInsn(ILOAD, context.var("_asm_flag_" + i));
        mw.visitInsn(IASTORE);
    }
    mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "parseRest", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;I[I)Ljava/lang/Object;");
    // cast
    mw.visitTypeInsn(CHECKCAST, type(context.clazz));
    mw.visitInsn(ARETURN);
    mw.visitLabel(super_);
    mw.visitVarInsn(ALOAD, 0);
    mw.visitVarInsn(ALOAD, 1);
    mw.visitVarInsn(ALOAD, 2);
    mw.visitVarInsn(ALOAD, 3);
    mw.visitVarInsn(ILOAD, 4);
    //
    mw.visitMethodInsn(//
    INVOKESPECIAL, //
    type(JavaBeanDeserializer.class), //
    "deserialze", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;");
    mw.visitInsn(ARETURN);
    mw.visitMaxs(10, context.variantIndex);
    mw.visitEnd();
}
Also used : JavaBeanInfo(com.alibaba.fastjson.util.JavaBeanInfo) MethodWriter(com.alibaba.fastjson.asm.MethodWriter) Label(com.alibaba.fastjson.asm.Label) Method(java.lang.reflect.Method) MethodVisitor(com.alibaba.fastjson.asm.MethodVisitor) ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ParseContext(com.alibaba.fastjson.parser.ParseContext) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Example 10 with ParseContext

use of com.alibaba.fastjson.parser.ParseContext in project fastjson by alibaba.

the class AwtCodec method deserialze.

@SuppressWarnings("unchecked")
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
    JSONLexer lexer = parser.lexer;
    if (lexer.token() == JSONToken.NULL) {
        lexer.nextToken(JSONToken.COMMA);
        return null;
    }
    if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
        throw new JSONException("syntax error");
    }
    lexer.nextToken();
    T obj;
    if (type == Point.class) {
        obj = (T) parsePoint(parser, fieldName);
    } else if (type == Rectangle.class) {
        obj = (T) parseRectangle(parser);
    } else if (type == Color.class) {
        obj = (T) parseColor(parser);
    } else if (type == Font.class) {
        obj = (T) parseFont(parser);
    } else {
        throw new JSONException("not support awt class : " + type);
    }
    ParseContext context = parser.getContext();
    parser.setContext(obj, fieldName);
    parser.setContext(context);
    return obj;
}
Also used : Rectangle(java.awt.Rectangle) ParseContext(com.alibaba.fastjson.parser.ParseContext) JSONException(com.alibaba.fastjson.JSONException) JSONLexer(com.alibaba.fastjson.parser.JSONLexer) Font(java.awt.Font)

Aggregations

ParseContext (com.alibaba.fastjson.parser.ParseContext)11 JSONLexerBase (com.alibaba.fastjson.parser.JSONLexerBase)5 ResolveTask (com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask)4 JSONException (com.alibaba.fastjson.JSONException)3 FieldInfo (com.alibaba.fastjson.util.FieldInfo)3 ParameterizedType (java.lang.reflect.ParameterizedType)3 Type (java.lang.reflect.Type)3 JSONObject (com.alibaba.fastjson.JSONObject)2 JSON (com.alibaba.fastjson.JSON)1 JSONField (com.alibaba.fastjson.annotation.JSONField)1 Label (com.alibaba.fastjson.asm.Label)1 MethodVisitor (com.alibaba.fastjson.asm.MethodVisitor)1 MethodWriter (com.alibaba.fastjson.asm.MethodWriter)1 DefaultJSONParser (com.alibaba.fastjson.parser.DefaultJSONParser)1 JSONLexer (com.alibaba.fastjson.parser.JSONLexer)1 ParserConfig (com.alibaba.fastjson.parser.ParserConfig)1 ContextObjectDeserializer (com.alibaba.fastjson.parser.deserializer.ContextObjectDeserializer)1 JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer)1 JavaBeanInfo (com.alibaba.fastjson.util.JavaBeanInfo)1 Font (java.awt.Font)1