Search in sources :

Example 6 with FieldInfo

use of com.alibaba.fastjson.util.FieldInfo in project fastjson by alibaba.

the class JavaBeanSerializer method write.

public //
void write(//
JSONSerializer serializer, //
Object object, //
Object fieldName, //
Type fieldType, int features) throws IOException {
    SerializeWriter out = serializer.out;
    if (object == null) {
        out.writeNull();
        return;
    }
    if (writeReference(serializer, object, features)) {
        return;
    }
    final FieldSerializer[] getters;
    if (out.sortField) {
        getters = this.sortedGetters;
    } else {
        getters = this.getters;
    }
    SerialContext parent = serializer.context;
    serializer.setContext(parent, object, fieldName, this.beanInfo.features, features);
    final boolean writeAsArray = isWriteAsArray(serializer, features);
    try {
        final char startSeperator = writeAsArray ? '[' : '{';
        final char endSeperator = writeAsArray ? ']' : '}';
        out.append(startSeperator);
        if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
            serializer.incrementIndent();
            serializer.println();
        }
        boolean commaFlag = false;
        if ((this.beanInfo.features & SerializerFeature.WriteClassName.mask) != 0 || serializer.isWriteClassName(fieldType, object)) {
            Class<?> objClass = object.getClass();
            if (objClass != fieldType) {
                writeClassName(serializer, object);
                commaFlag = true;
            }
        }
        char seperator = commaFlag ? ',' : '\0';
        final boolean directWritePrefix = out.quoteFieldNames && !out.useSingleQuotes;
        char newSeperator = this.writeBefore(serializer, object, seperator);
        commaFlag = newSeperator == ',';
        final boolean skipTransient = out.isEnabled(SerializerFeature.SkipTransientField);
        final boolean ignoreNonFieldGetter = out.isEnabled(SerializerFeature.IgnoreNonFieldGetter);
        for (int i = 0; i < getters.length; ++i) {
            FieldSerializer fieldSerializer = getters[i];
            Field field = fieldSerializer.fieldInfo.field;
            FieldInfo fieldInfo = fieldSerializer.fieldInfo;
            String fieldInfoName = fieldInfo.name;
            Class<?> fieldClass = fieldInfo.fieldClass;
            if (skipTransient) {
                if (field != null) {
                    if (fieldInfo.fieldTransient) {
                        continue;
                    }
                }
            }
            if (ignoreNonFieldGetter) {
                if (field == null) {
                    continue;
                }
            }
            if (//
            (!this.applyName(serializer, object, fieldInfo.name)) || !this.applyLabel(serializer, fieldInfo.label)) {
                continue;
            }
            Object propertyValue;
            try {
                propertyValue = fieldSerializer.getPropertyValueDirect(object);
            } catch (InvocationTargetException ex) {
                if (out.isEnabled(SerializerFeature.IgnoreErrorGetter)) {
                    propertyValue = null;
                } else {
                    throw ex;
                }
            }
            if (!this.apply(serializer, object, fieldInfoName, propertyValue)) {
                continue;
            }
            String key = fieldInfoName;
            key = this.processKey(serializer, object, key, propertyValue);
            Object originalValue = propertyValue;
            propertyValue = this.processValue(serializer, fieldSerializer.fieldContext, object, fieldInfoName, propertyValue);
            if (propertyValue == null && !writeAsArray) {
                if ((!fieldSerializer.writeNull) && (!out.isEnabled(SerializerFeature.WRITE_MAP_NULL_FEATURES))) {
                    continue;
                }
            }
            if (propertyValue != null && out.notWriteDefaultValue) {
                Class<?> fieldCLass = fieldInfo.fieldClass;
                if (fieldCLass == byte.class && propertyValue instanceof Byte && ((Byte) propertyValue).byteValue() == 0) {
                    continue;
                } else if (fieldCLass == short.class && propertyValue instanceof Short && ((Short) propertyValue).shortValue() == 0) {
                    continue;
                } else if (fieldCLass == int.class && propertyValue instanceof Integer && ((Integer) propertyValue).intValue() == 0) {
                    continue;
                } else if (fieldCLass == long.class && propertyValue instanceof Long && ((Long) propertyValue).longValue() == 0L) {
                    continue;
                } else if (fieldCLass == float.class && propertyValue instanceof Float && ((Float) propertyValue).floatValue() == 0F) {
                    continue;
                } else if (fieldCLass == double.class && propertyValue instanceof Double && ((Double) propertyValue).doubleValue() == 0D) {
                    continue;
                } else if (fieldCLass == boolean.class && propertyValue instanceof Boolean && !((Boolean) propertyValue).booleanValue()) {
                    continue;
                }
            }
            if (commaFlag) {
                out.write(',');
                if (out.isEnabled(SerializerFeature.PrettyFormat)) {
                    serializer.println();
                }
            }
            if (key != fieldInfoName) {
                if (!writeAsArray) {
                    out.writeFieldName(key, true);
                }
                serializer.write(propertyValue);
            } else if (originalValue != propertyValue) {
                if (!writeAsArray) {
                    fieldSerializer.writePrefix(serializer);
                }
                serializer.write(propertyValue);
            } else {
                if (!writeAsArray) {
                    if (directWritePrefix) {
                        out.write(fieldInfo.name_chars, 0, fieldInfo.name_chars.length);
                    } else {
                        fieldSerializer.writePrefix(serializer);
                    }
                }
                if (!writeAsArray) {
                    JSONField fieldAnnotation = fieldInfo.getAnnotation();
                    if (fieldClass == String.class && (fieldAnnotation == null || fieldAnnotation.serializeUsing() == Void.class)) {
                        if (propertyValue == null) {
                            if ((out.features & SerializerFeature.WriteNullStringAsEmpty.mask) != 0 || (fieldSerializer.features & SerializerFeature.WriteNullStringAsEmpty.mask) != 0) {
                                out.writeString("");
                            } else {
                                out.writeNull();
                            }
                        } else {
                            String propertyValueString = (String) propertyValue;
                            if (out.useSingleQuotes) {
                                out.writeStringWithSingleQuote(propertyValueString);
                            } else {
                                out.writeStringWithDoubleQuote(propertyValueString, (char) 0);
                            }
                        }
                    } else {
                        fieldSerializer.writeValue(serializer, propertyValue);
                    }
                } else {
                    fieldSerializer.writeValue(serializer, propertyValue);
                }
            }
            commaFlag = true;
        }
        this.writeAfter(serializer, object, commaFlag ? ',' : '\0');
        if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
            serializer.decrementIdent();
            serializer.println();
        }
        out.append(endSeperator);
    } catch (Exception e) {
        String errorMessage = "write javaBean error";
        if (object != null) {
            errorMessage += ", class " + object.getClass().getName();
        }
        if (fieldName != null) {
            errorMessage += ", fieldName : " + fieldName;
        }
        if (e.getMessage() != null) {
            errorMessage += (", " + e.getMessage());
        }
        throw new JSONException(errorMessage, e);
    } finally {
        serializer.context = parent;
    }
}
Also used : JSONField(com.alibaba.fastjson.annotation.JSONField) JSONException(com.alibaba.fastjson.JSONException) InvocationTargetException(java.lang.reflect.InvocationTargetException) JSONException(com.alibaba.fastjson.JSONException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) JSONField(com.alibaba.fastjson.annotation.JSONField) Field(java.lang.reflect.Field) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Example 7 with FieldInfo

use of com.alibaba.fastjson.util.FieldInfo in project fastjson by alibaba.

the class SerializeConfig method createJavaBeanSerializer.

public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) {
    JSONType jsonType = beanInfo.jsonType;
    if (jsonType != null) {
        Class<?> serializerClass = jsonType.serializer();
        if (serializerClass != Void.class) {
            try {
                Object seralizer = serializerClass.newInstance();
                if (seralizer instanceof ObjectSerializer) {
                    return (ObjectSerializer) seralizer;
                }
            } catch (Throwable e) {
            // skip
            }
        }
        if (jsonType.asm() == false) {
            asm = false;
        }
    }
    Class<?> clazz = beanInfo.beanType;
    if (!Modifier.isPublic(beanInfo.beanType.getModifiers())) {
        return new JavaBeanSerializer(beanInfo);
    }
    boolean asm = this.asm;
    if (asm && asmFactory.classLoader.isExternalClass(clazz) || clazz == Serializable.class || clazz == Object.class) {
        asm = false;
    }
    if (asm && !ASMUtils.checkName(clazz.getSimpleName())) {
        asm = false;
    }
    if (asm) {
        for (FieldInfo fieldInfo : beanInfo.fields) {
            Field field = fieldInfo.field;
            if (field != null && !field.getType().equals(fieldInfo.fieldClass)) {
                asm = false;
                break;
            }
            Method method = fieldInfo.method;
            if (method != null && !method.getReturnType().equals(fieldInfo.fieldClass)) {
                asm = false;
                break;
            }
            JSONField annotation = fieldInfo.getAnnotation();
            if (annotation == null) {
                continue;
            }
            if (//
            (!ASMUtils.checkName(annotation.name())) || annotation.format().length() != 0 || annotation.jsonDirect() || annotation.serializeUsing() != Void.class) {
                asm = false;
                break;
            }
            for (SerializerFeature feature : annotation.serialzeFeatures()) {
                if (SerializerFeature.WriteNonStringValueAsString == feature || SerializerFeature.WriteEnumUsingToString == feature) {
                    asm = false;
                    break;
                }
            }
        }
    }
    if (asm) {
        try {
            ObjectSerializer asmSerializer = createASMSerializer(beanInfo);
            if (asmSerializer != null) {
                return asmSerializer;
            }
        } catch (ClassFormatError e) {
        // skip
        } catch (ClassCastException e) {
        // skip
        } catch (Throwable e) {
            throw new JSONException("create asm serializer error, class " + clazz, e);
        }
    }
    return new JavaBeanSerializer(beanInfo);
}
Also used : JSONField(com.alibaba.fastjson.annotation.JSONField) JSONException(com.alibaba.fastjson.JSONException) Method(java.lang.reflect.Method) JSONField(com.alibaba.fastjson.annotation.JSONField) Field(java.lang.reflect.Field) JSONType(com.alibaba.fastjson.annotation.JSONType) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Example 8 with FieldInfo

use of com.alibaba.fastjson.util.FieldInfo in project fastjson by alibaba.

the class ASMSerializerFactory method generateWriteAsArray.

private void generateWriteAsArray(Class<?> clazz, MethodVisitor mw, FieldInfo[] getters, Context context) throws Exception {
    mw.visitVarInsn(ALOAD, context.var("out"));
    mw.visitVarInsn(BIPUSH, '[');
    mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
    int size = getters.length;
    if (size == 0) {
        mw.visitVarInsn(ALOAD, context.var("out"));
        mw.visitVarInsn(BIPUSH, ']');
        mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        return;
    }
    for (int i = 0; i < size; ++i) {
        final char seperator = (i == size - 1) ? ']' : ',';
        FieldInfo fieldInfo = getters[i];
        Class<?> fieldClass = fieldInfo.fieldClass;
        mw.visitLdcInsn(fieldInfo.name);
        mw.visitVarInsn(ASTORE, Context.fieldName);
        if (//
        fieldClass == byte.class || //
        fieldClass == short.class || fieldClass == int.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitInsn(DUP);
            _get(mw, context, fieldInfo);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeInt", "(I)V");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else if (fieldClass == long.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitInsn(DUP);
            _get(mw, context, fieldInfo);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeLong", "(J)V");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else if (fieldClass == float.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitInsn(DUP);
            _get(mw, context, fieldInfo);
            mw.visitInsn(ICONST_1);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeFloat", "(FZ)V");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else if (fieldClass == double.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitInsn(DUP);
            _get(mw, context, fieldInfo);
            mw.visitInsn(ICONST_1);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeDouble", "(DZ)V");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else if (fieldClass == boolean.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitInsn(DUP);
            _get(mw, context, fieldInfo);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(Z)V");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else if (fieldClass == char.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            // Character.toString(value)
            _get(mw, context, fieldInfo);
            mw.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "toString", "(C)Ljava/lang/String;");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeString", "(Ljava/lang/String;C)V");
        } else if (fieldClass == String.class) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            _get(mw, context, fieldInfo);
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeString", "(Ljava/lang/String;C)V");
        } else if (fieldClass.isEnum()) {
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitInsn(DUP);
            _get(mw, context, fieldInfo);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeEnum", "(Ljava/lang/Enum;)V");
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else if (List.class.isAssignableFrom(fieldClass)) {
            Type fieldType = fieldInfo.fieldType;
            Type elementType;
            if (fieldType instanceof Class) {
                elementType = Object.class;
            } else {
                elementType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
            }
            Class<?> elementClass = null;
            if (elementType instanceof Class<?>) {
                elementClass = (Class<?>) elementType;
                if (elementClass == Object.class) {
                    elementClass = null;
                }
            }
            _get(mw, context, fieldInfo);
            // cast
            mw.visitTypeInsn(CHECKCAST, "java/util/List");
            mw.visitVarInsn(ASTORE, context.var("list"));
            if (//
            elementClass == String.class && context.writeDirect) {
                mw.visitVarInsn(ALOAD, context.var("out"));
                mw.visitVarInsn(ALOAD, context.var("list"));
                mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(Ljava/util/List;)V");
            } else {
                Label nullEnd_ = new Label(), nullElse_ = new Label();
                mw.visitVarInsn(ALOAD, context.var("list"));
                mw.visitJumpInsn(IFNONNULL, nullElse_);
                mw.visitVarInsn(ALOAD, context.var("out"));
                mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeNull", "()V");
                mw.visitJumpInsn(GOTO, nullEnd_);
                mw.visitLabel(nullElse_);
                mw.visitVarInsn(ALOAD, context.var("list"));
                mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I");
                mw.visitVarInsn(ISTORE, context.var("size"));
                mw.visitVarInsn(ALOAD, context.var("out"));
                mw.visitVarInsn(BIPUSH, '[');
                mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
                Label for_ = new Label(), forFirst_ = new Label(), forEnd_ = new Label();
                mw.visitInsn(ICONST_0);
                mw.visitVarInsn(ISTORE, context.var("i"));
                // for (; i < list.size() -1; ++i) {
                mw.visitLabel(for_);
                mw.visitVarInsn(ILOAD, context.var("i"));
                mw.visitVarInsn(ILOAD, context.var("size"));
                // i < list.size - 1
                mw.visitJumpInsn(IF_ICMPGE, forEnd_);
                mw.visitVarInsn(ILOAD, context.var("i"));
                // i < list.size - 1
                mw.visitJumpInsn(IFEQ, forFirst_);
                mw.visitVarInsn(ALOAD, context.var("out"));
                mw.visitVarInsn(BIPUSH, ',');
                mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
                mw.visitLabel(forFirst_);
                mw.visitVarInsn(ALOAD, context.var("list"));
                mw.visitVarInsn(ILOAD, context.var("i"));
                mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;");
                mw.visitVarInsn(ASTORE, context.var("list_item"));
                Label forItemNullEnd_ = new Label(), forItemNullElse_ = new Label();
                mw.visitVarInsn(ALOAD, context.var("list_item"));
                mw.visitJumpInsn(IFNONNULL, forItemNullElse_);
                mw.visitVarInsn(ALOAD, context.var("out"));
                mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeNull", "()V");
                mw.visitJumpInsn(GOTO, forItemNullEnd_);
                mw.visitLabel(forItemNullElse_);
                Label forItemClassIfEnd_ = new Label(), forItemClassIfElse_ = new Label();
                if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) {
                    mw.visitVarInsn(ALOAD, context.var("list_item"));
                    mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
                    mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(elementClass)));
                    mw.visitJumpInsn(IF_ACMPNE, forItemClassIfElse_);
                    _getListFieldItemSer(context, mw, fieldInfo, elementClass);
                    mw.visitVarInsn(ASTORE, context.var("list_item_desc"));
                    Label instanceOfElse_ = new Label(), instanceOfEnd_ = new Label();
                    if (context.writeDirect) {
                        mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
                        mw.visitTypeInsn(INSTANCEOF, JavaBeanSerializer);
                        mw.visitJumpInsn(IFEQ, instanceOfElse_);
                        mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
                        // cast
                        mw.visitTypeInsn(CHECKCAST, JavaBeanSerializer);
                        mw.visitVarInsn(ALOAD, Context.serializer);
                        // object
                        mw.visitVarInsn(ALOAD, context.var("list_item"));
                        if (context.nonContext) {
                            // fieldName
                            mw.visitInsn(ACONST_NULL);
                        } else {
                            mw.visitVarInsn(ILOAD, context.var("i"));
                            mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
                        }
                        // fieldType
                        mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(elementClass)));
                        // features
                        mw.visitLdcInsn(fieldInfo.serialzeFeatures);
                        //
                        mw.visitMethodInsn(//
                        INVOKEVIRTUAL, //
                        JavaBeanSerializer, //
                        "writeAsArrayNonContext", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
                        mw.visitJumpInsn(GOTO, instanceOfEnd_);
                        mw.visitLabel(instanceOfElse_);
                    }
                    mw.visitVarInsn(ALOAD, context.var("list_item_desc"));
                    mw.visitVarInsn(ALOAD, Context.serializer);
                    // object
                    mw.visitVarInsn(ALOAD, context.var("list_item"));
                    if (context.nonContext) {
                        // fieldName
                        mw.visitInsn(ACONST_NULL);
                    } else {
                        mw.visitVarInsn(ILOAD, context.var("i"));
                        mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
                    }
                    // fieldType
                    mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(elementClass)));
                    // features
                    mw.visitLdcInsn(fieldInfo.serialzeFeatures);
                    //
                    mw.visitMethodInsn(//
                    INVOKEINTERFACE, //
                    ObjectSerializer, //
                    "write", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
                    mw.visitLabel(instanceOfEnd_);
                    mw.visitJumpInsn(GOTO, forItemClassIfEnd_);
                }
                mw.visitLabel(forItemClassIfElse_);
                mw.visitVarInsn(ALOAD, Context.serializer);
                mw.visitVarInsn(ALOAD, context.var("list_item"));
                if (context.nonContext) {
                    mw.visitInsn(ACONST_NULL);
                } else {
                    mw.visitVarInsn(ILOAD, context.var("i"));
                    mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
                }
                if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) {
                    mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc((Class<?>) elementType)));
                    mw.visitLdcInsn(fieldInfo.serialzeFeatures);
                    mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeWithFieldName", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
                } else {
                    mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeWithFieldName", "(Ljava/lang/Object;Ljava/lang/Object;)V");
                }
                mw.visitLabel(forItemClassIfEnd_);
                mw.visitLabel(forItemNullEnd_);
                mw.visitIincInsn(context.var("i"), 1);
                mw.visitJumpInsn(GOTO, for_);
                mw.visitLabel(forEnd_);
                mw.visitVarInsn(ALOAD, context.var("out"));
                mw.visitVarInsn(BIPUSH, ']');
                mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
                mw.visitLabel(nullEnd_);
            }
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        } else {
            Label notNullEnd_ = new Label(), notNullElse_ = new Label();
            _get(mw, context, fieldInfo);
            mw.visitInsn(DUP);
            mw.visitVarInsn(ASTORE, context.var("field_" + fieldInfo.fieldClass.getName()));
            mw.visitJumpInsn(IFNONNULL, notNullElse_);
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeNull", "()V");
            mw.visitJumpInsn(GOTO, notNullEnd_);
            mw.visitLabel(notNullElse_);
            Label classIfEnd_ = new Label(), classIfElse_ = new Label();
            mw.visitVarInsn(ALOAD, context.var("field_" + fieldInfo.fieldClass.getName()));
            mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
            mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
            mw.visitJumpInsn(IF_ACMPNE, classIfElse_);
            _getFieldSer(context, mw, fieldInfo);
            mw.visitVarInsn(ASTORE, context.var("fied_ser"));
            Label instanceOfElse_ = new Label(), instanceOfEnd_ = new Label();
            if (context.writeDirect && Modifier.isPublic(fieldClass.getModifiers())) {
                mw.visitVarInsn(ALOAD, context.var("fied_ser"));
                mw.visitTypeInsn(INSTANCEOF, JavaBeanSerializer);
                mw.visitJumpInsn(IFEQ, instanceOfElse_);
                mw.visitVarInsn(ALOAD, context.var("fied_ser"));
                // cast
                mw.visitTypeInsn(CHECKCAST, JavaBeanSerializer);
                mw.visitVarInsn(ALOAD, Context.serializer);
                mw.visitVarInsn(ALOAD, context.var("field_" + fieldInfo.fieldClass.getName()));
                mw.visitVarInsn(ALOAD, Context.fieldName);
                // fieldType
                mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
                // features
                mw.visitLdcInsn(fieldInfo.serialzeFeatures);
                //
                mw.visitMethodInsn(//
                INVOKEVIRTUAL, //
                JavaBeanSerializer, //
                "writeAsArrayNonContext", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
                mw.visitJumpInsn(GOTO, instanceOfEnd_);
                mw.visitLabel(instanceOfElse_);
            }
            mw.visitVarInsn(ALOAD, context.var("fied_ser"));
            mw.visitVarInsn(ALOAD, Context.serializer);
            mw.visitVarInsn(ALOAD, context.var("field_" + fieldInfo.fieldClass.getName()));
            mw.visitVarInsn(ALOAD, Context.fieldName);
            // fieldType
            mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
            // features
            mw.visitLdcInsn(fieldInfo.serialzeFeatures);
            //
            mw.visitMethodInsn(//
            INVOKEINTERFACE, //
            ObjectSerializer, //
            "write", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
            mw.visitLabel(instanceOfEnd_);
            mw.visitJumpInsn(GOTO, classIfEnd_);
            mw.visitLabel(classIfElse_);
            String format = fieldInfo.getFormat();
            mw.visitVarInsn(ALOAD, Context.serializer);
            mw.visitVarInsn(ALOAD, context.var("field_" + fieldInfo.fieldClass.getName()));
            if (format != null) {
                mw.visitLdcInsn(format);
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeWithFormat", "(Ljava/lang/Object;Ljava/lang/String;)V");
            } else {
                mw.visitVarInsn(ALOAD, Context.fieldName);
                if (//
                fieldInfo.fieldType instanceof Class<?> && ((Class<?>) fieldInfo.fieldType).isPrimitive()) {
                    mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeWithFieldName", "(Ljava/lang/Object;Ljava/lang/Object;)V");
                } else {
                    // this
                    mw.visitVarInsn(ALOAD, 0);
                    mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_fieldType", "Ljava/lang/reflect/Type;");
                    mw.visitLdcInsn(fieldInfo.serialzeFeatures);
                    mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeWithFieldName", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
                }
            }
            mw.visitLabel(classIfEnd_);
            mw.visitLabel(notNullEnd_);
            mw.visitVarInsn(ALOAD, context.var("out"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
        }
    }
}
Also used : JSONType(com.alibaba.fastjson.annotation.JSONType) Label(com.alibaba.fastjson.asm.Label) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Example 9 with FieldInfo

use of com.alibaba.fastjson.util.FieldInfo in project fastjson by alibaba.

the class DeserializerGen method genDeserialze.

protected void genDeserialze() throws IOException {
    if (beanInfo.fields.length == 0) {
        return;
    }
    for (FieldInfo fieldInfo : beanInfo.fields) {
        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;
            }
        }
    }
    FieldInfo[] fieldList = beanInfo.sortedFields;
    println();
    print("public Object deserialze(DefaultJSONParser parser, Type type, Object fieldName) {");
    incrementIndent();
    println();
    println("JSONLexerBase lexer = (JSONLexerBase) parser.getLexer();");
    println();
    println("if (!lexer.isEnabled(Feature.SortFeidFastMatch)) {");
    println("\treturn super.deserialze(parser, type, fieldName);");
    println("}");
    println();
    println("if (isSupportArrayToBean(lexer)) {");
    println("\t// deserialzeArrayMapping");
    println("}");
    println();
    println("if (lexer.scanType(\"Department\") == JSONLexerBase.NOT_MATCH) {");
    println("\treturn super.deserialze(parser, type, fieldName);");
    println("}");
    println();
    println("ParseContext mark_context = parser.getContext();");
    println("int matchedCount = 0;");
    print(clazz.getSimpleName());
    print(" instance = ");
    Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
    if (Modifier.isPublic(defaultConstructor.getModifiers())) {
        print("new ");
        print(clazz.getSimpleName());
        println("();");
    } else {
        print("(");
        print(clazz.getSimpleName());
        print(") createInstance(parser);");
    }
    println();
    println("ParseContext context = parser.getContext();");
    println("ParseContext childContext = parser.setContext(context, instance, fieldName);");
    println();
    println("if (lexer.matchStat == JSONLexerBase.END) {");
    println("\treturn instance;");
    println("}");
    println();
    println("int matchStat = 0;");
    int fieldListSize = fieldList.length;
    for (int i = 0; i < fieldListSize; i += 32) {
        print("int _asm_flag_");
        print(Integer.toString(i / 32));
        println(" = 0;");
    }
    for (int i = 0; i < fieldListSize; ++i) {
        FieldInfo fieldInfo = fieldList[i];
        Class<?> fieldClass = fieldInfo.fieldClass;
        if (fieldClass == boolean.class) {
            print("boolean ");
            printFieldVarName(fieldInfo);
            println(" = false;");
        } else if (//
        fieldClass == byte.class || //
        fieldClass == short.class || //
        fieldClass == int.class || //
        fieldClass == long.class || //
        fieldClass == float.class || //
        fieldClass == double.class) {
            print(fieldClass.getSimpleName());
            print(" ");
            printFieldVarName(fieldInfo);
            println(" = 0;");
        } else {
            if (fieldClass == String.class) {
                print("String ");
                printFieldVarName(fieldInfo);
                println(";");
                println("if (lexer.isEnabled(Feature.InitStringFieldAsEmpty)) {");
                print("\t");
                printFieldVarName(fieldInfo);
                println(" = lexer.stringDefaultValue();");
                print("\t");
                genSetFlag(i);
                println("} else {");
                print("\t");
                printFieldVarName(fieldInfo);
                println(" = null;");
                println("}");
            } else {
                printClassName(fieldClass);
                print(" ");
                printFieldVarName(fieldInfo);
                print(" = null;");
                println();
            }
        }
    }
    println("boolean endFlag = false, restFlag = false;");
    println();
    for (int i = 0; i < fieldListSize; ++i) {
        print("if ((!endFlag) && (!restFlag)) {");
        incrementIndent();
        println();
        FieldInfo fieldInfo = fieldList[i];
        Class<?> fieldClass = fieldInfo.fieldClass;
        Type fieldType = fieldInfo.fieldType;
        if (fieldClass == boolean.class) {
            printFieldVarName(fieldInfo);
            print(" = lexer.scanFieldBoolean(");
            printFieldPrefix(fieldInfo);
            println(");");
        } else if (fieldClass == byte.class || fieldClass == short.class || fieldClass == int.class) {
            printFieldVarName(fieldInfo);
            print(" = lexer.scanFieldInt(");
            printFieldPrefix(fieldInfo);
            println(");");
        } else if (fieldClass == long.class) {
            printFieldVarName(fieldInfo);
            print(" = lexer.scanFieldLong(");
            printFieldPrefix(fieldInfo);
            println(");");
        } else if (fieldClass == float.class) {
            printFieldVarName(fieldInfo);
            print(" = lexer.scanFieldFloat(");
            printFieldPrefix(fieldInfo);
            println(");");
        } else if (fieldClass == double.class) {
            printFieldVarName(fieldInfo);
            print(" = lexer.scanFieldDouble(");
            printFieldPrefix(fieldInfo);
            println(");");
        } else if (fieldClass == String.class) {
            printFieldVarName(fieldInfo);
            print(" = lexer.scanFieldString(");
            printFieldPrefix(fieldInfo);
            println(");");
        } else if (fieldClass.isEnum()) {
            print("String ");
            printFieldVarEnumName(fieldInfo);
            print(" = lexer.scanFieldSymbol(");
            printFieldPrefix(fieldInfo);
            println(", parser.getSymbolTable());");
            print("if (");
            printFieldVarEnumName(fieldInfo);
            println(" == null) {");
            print("\t");
            printFieldVarName(fieldInfo);
            print(" = ");
            printClassName(fieldClass);
            print(".valueOf(");
            printFieldVarEnumName(fieldInfo);
            println(");");
            println("}");
        } else if (Collection.class.isAssignableFrom(fieldClass)) {
            Class<?> itemClass = TypeUtils.getCollectionItemClass(fieldType);
            if (itemClass == String.class) {
                printFieldVarName(fieldInfo);
                print(" = (");
                printClassName(fieldClass);
                print(") lexer.scanFieldStringArray(");
                printFieldPrefix(fieldInfo);
                print(", ");
                printClassName(fieldClass);
                print(".class);");
                println();
            } else {
                genDeserialzeList(fieldInfo, i, itemClass);
                if (i == fieldListSize - 1) {
                    genEndCheck();
                }
            }
        } else {
            genDeserialzeObject(fieldInfo, i);
            if (i == fieldListSize - 1) {
                genEndCheck();
            }
        }
        println("if(lexer.matchStat > 0) {");
        print("\t");
        genSetFlag(i);
        println("\tmatchedCount++;");
        println("}");
        println("if(lexer.matchStat == JSONLexerBase.NOT_MATCH) {");
        println("\trestFlag = true;");
        println("}");
        println("if(lexer.matchStat != JSONLexerBase.END) {");
        println("\tendFlag = true;");
        println("}");
        decrementIndent();
        println();
        println("}");
    }
    genBatchSet(fieldList, true);
    println();
    println("if (restFlag) {");
    println("\treturn super.parseRest(parser, type, fieldName, instance);");
    println("}");
    println();
    print("return instance;");
    println();
    decrementIndent();
    println();
    print("}");
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Collection(java.util.Collection) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Example 10 with FieldInfo

use of com.alibaba.fastjson.util.FieldInfo in project fastjson by alibaba.

the class FieldInfoTest method test_null.

public void test_null() throws Exception {
    FieldInfo fieldInfo = new FieldInfo("getValue", Entity.class.getMethod("getValue"), null, null, null, 0, 0, 0, null, null, null);
    Assert.assertEquals(null, fieldInfo.getAnnotation());
    Field field = GenericFieldEntity.class.getField("value");
    Type type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericFieldEntity.class);
    FieldInfo fieldInfoOfField = new FieldInfo("value", null, field, GenericFieldEntity.class, type, 0, 0, 0, null, null, null);
    Assert.assertEquals(fieldInfoOfField.fieldType, ValueObject.class);
    Assert.assertEquals(fieldInfoOfField.fieldClass, ValueObject.class);
    field = GenericListFieldEntity.class.getField("value");
    type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericListFieldEntity.class);
    FieldInfo fieldInfoOfListField = new FieldInfo("value", null, field, GenericListFieldEntity.class, type, 0, 0, 0, null, null, null);
    ParameterizedTypeImpl actualFieldType = (ParameterizedTypeImpl) fieldInfoOfListField.fieldType;
    Assert.assertEquals(actualFieldType.getActualTypeArguments()[0], ValueObject.class);
    Assert.assertEquals(actualFieldType.getRawType(), List.class);
    Assert.assertEquals(fieldInfoOfListField.fieldClass, List.class);
    Assert.assertEquals(null, ((ParameterizedTypeImpl) type).getOwnerType());
    Method method = GenericSetterEntity.class.getMethod("setValue", Object.class);
    type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericSetterEntity.class);
    FieldInfo fieldInfoOfSetter = new FieldInfo("value", method, null, GenericSetterEntity.class, type, 0, 0, 0, null, null, null);
    Assert.assertEquals(fieldInfoOfSetter.fieldType, ValueObject.class);
    Assert.assertEquals(fieldInfoOfSetter.fieldClass, ValueObject.class);
    fieldInfoOfSetter.toString();
    method = GenericListSetterEntity.class.getMethod("setValue", List.class);
    type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericListSetterEntity.class);
    FieldInfo fieldInfoOfListSetter = new FieldInfo("value", method, null, GenericListSetterEntity.class, type, 0, 0, 0, null, null, null);
    Assert.assertEquals(actualFieldType.getActualTypeArguments()[0], ValueObject.class);
    Assert.assertEquals(actualFieldType.getRawType(), List.class);
    Assert.assertEquals(fieldInfoOfListSetter.fieldClass, List.class);
}
Also used : Field(java.lang.reflect.Field) Type(java.lang.reflect.Type) List(java.util.List) Method(java.lang.reflect.Method) ParameterizedTypeImpl(com.alibaba.fastjson.util.ParameterizedTypeImpl) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Aggregations

FieldInfo (com.alibaba.fastjson.util.FieldInfo)20 JSONException (com.alibaba.fastjson.JSONException)7 Label (com.alibaba.fastjson.asm.Label)6 JSONObject (com.alibaba.fastjson.JSONObject)4 JSONField (com.alibaba.fastjson.annotation.JSONField)4 MethodVisitor (com.alibaba.fastjson.asm.MethodVisitor)4 MethodWriter (com.alibaba.fastjson.asm.MethodWriter)4 Type (java.lang.reflect.Type)4 JSON (com.alibaba.fastjson.JSON)3 JSONType (com.alibaba.fastjson.annotation.JSONType)3 ParseContext (com.alibaba.fastjson.parser.ParseContext)3 Field (java.lang.reflect.Field)3 Method (java.lang.reflect.Method)3 ParameterizedType (java.lang.reflect.ParameterizedType)3 Collection (java.util.Collection)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 FieldWriter (com.alibaba.fastjson.asm.FieldWriter)2 JavaBeanInfo (com.alibaba.fastjson.util.JavaBeanInfo)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2