Search in sources :

Example 1 with PropertyNamingStrategy

use of com.alibaba.fastjson.PropertyNamingStrategy in project uavstack by uavorg.

the class JavaBeanInfo method build.

public static // 
JavaBeanInfo build(// 
Class<?> clazz, // 
Type type, // 
PropertyNamingStrategy propertyNamingStrategy, // 
boolean fieldBased, boolean compatibleWithJavaBean, boolean jacksonCompatible) {
    JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
    if (jsonType != null) {
        PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
        if (jsonTypeNaming != null && jsonTypeNaming != PropertyNamingStrategy.CamelCase) {
            propertyNamingStrategy = jsonTypeNaming;
        }
    }
    Class<?> builderClass = getBuilderClass(clazz, jsonType);
    Field[] declaredFields = clazz.getDeclaredFields();
    Method[] methods = clazz.getMethods();
    boolean kotlin = TypeUtils.isKotlin(clazz);
    Constructor[] constructors = clazz.getDeclaredConstructors();
    Constructor<?> defaultConstructor = null;
    if ((!kotlin) || constructors.length == 1) {
        if (builderClass == null) {
            defaultConstructor = getDefaultConstructor(clazz, constructors);
        } else {
            defaultConstructor = getDefaultConstructor(builderClass, builderClass.getDeclaredConstructors());
        }
    }
    Constructor<?> creatorConstructor = null;
    Method buildMethod = null;
    Method factoryMethod = null;
    List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
    if (fieldBased) {
        for (Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) {
            Field[] fields = currentClass.getDeclaredFields();
            computeFields(clazz, type, propertyNamingStrategy, fieldList, fields);
        }
        return new JavaBeanInfo(clazz, builderClass, defaultConstructor, null, factoryMethod, buildMethod, jsonType, fieldList);
    }
    boolean isInterfaceOrAbstract = clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers());
    if ((defaultConstructor == null && builderClass == null) || isInterfaceOrAbstract) {
        creatorConstructor = getCreatorConstructor(constructors);
        if (creatorConstructor != null && !isInterfaceOrAbstract) {
            // 基于标记 JSONCreator 注解的构造方法
            TypeUtils.setAccessible(creatorConstructor);
            Class<?>[] types = creatorConstructor.getParameterTypes();
            String[] lookupParameterNames = null;
            if (types.length > 0) {
                Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
                for (int i = 0; i < types.length; ++i) {
                    Annotation[] paramAnnotations = paramAnnotationArrays[i];
                    JSONField fieldAnnotation = null;
                    for (Annotation paramAnnotation : paramAnnotations) {
                        if (paramAnnotation instanceof JSONField) {
                            fieldAnnotation = (JSONField) paramAnnotation;
                            break;
                        }
                    }
                    Class<?> fieldClass = types[i];
                    Type fieldType = creatorConstructor.getGenericParameterTypes()[i];
                    String fieldName = null;
                    Field field = null;
                    int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
                    if (fieldAnnotation != null) {
                        field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields);
                        ordinal = fieldAnnotation.ordinal();
                        serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                        parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                        fieldName = fieldAnnotation.name();
                    }
                    if (fieldName == null || fieldName.length() == 0) {
                        if (lookupParameterNames == null) {
                            lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor);
                        }
                        fieldName = lookupParameterNames[i];
                    }
                    FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures);
                    add(fieldList, fieldInfo);
                }
            }
        // return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList);
        } else if ((factoryMethod = getFactoryMethod(clazz, methods, jacksonCompatible)) != null) {
            TypeUtils.setAccessible(factoryMethod);
            String[] lookupParameterNames = null;
            Class<?>[] types = factoryMethod.getParameterTypes();
            if (types.length > 0) {
                Annotation[][] paramAnnotationArrays = factoryMethod.getParameterAnnotations();
                for (int i = 0; i < types.length; ++i) {
                    Annotation[] paramAnnotations = paramAnnotationArrays[i];
                    JSONField fieldAnnotation = null;
                    for (Annotation paramAnnotation : paramAnnotations) {
                        if (paramAnnotation instanceof JSONField) {
                            fieldAnnotation = (JSONField) paramAnnotation;
                            break;
                        }
                    }
                    if (fieldAnnotation == null && !(jacksonCompatible && TypeUtils.isJacksonCreator(factoryMethod))) {
                        throw new JSONException("illegal json creator");
                    }
                    String fieldName = null;
                    int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
                    if (fieldAnnotation != null) {
                        fieldName = fieldAnnotation.name();
                        ordinal = fieldAnnotation.ordinal();
                        serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                        parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                    }
                    if (fieldName == null || fieldName.length() == 0) {
                        if (lookupParameterNames == null) {
                            lookupParameterNames = ASMUtils.lookupParameterNames(factoryMethod);
                        }
                        fieldName = lookupParameterNames[i];
                    }
                    Class<?> fieldClass = types[i];
                    Type fieldType = factoryMethod.getGenericParameterTypes()[i];
                    Field field = TypeUtils.getField(clazz, fieldName, declaredFields);
                    FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures);
                    add(fieldList, fieldInfo);
                }
                return new JavaBeanInfo(clazz, builderClass, null, null, factoryMethod, null, jsonType, fieldList);
            }
        } else if (!isInterfaceOrAbstract) {
            String className = clazz.getName();
            String[] paramNames = null;
            if (kotlin && constructors.length > 0) {
                paramNames = TypeUtils.getKoltinConstructorParameters(clazz);
                creatorConstructor = TypeUtils.getKoltinConstructor(constructors, paramNames);
                TypeUtils.setAccessible(creatorConstructor);
            } else {
                for (Constructor constructor : constructors) {
                    Class<?>[] parameterTypes = constructor.getParameterTypes();
                    if (className.equals("org.springframework.security.web.authentication.WebAuthenticationDetails")) {
                        if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) {
                            creatorConstructor = constructor;
                            creatorConstructor.setAccessible(true);
                            paramNames = ASMUtils.lookupParameterNames(constructor);
                            break;
                        }
                    }
                    if (className.equals("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken")) {
                        if (parameterTypes.length == 3 && parameterTypes[0] == Object.class && parameterTypes[1] == Object.class && parameterTypes[2] == Collection.class) {
                            creatorConstructor = constructor;
                            creatorConstructor.setAccessible(true);
                            paramNames = new String[] { "principal", "credentials", "authorities" };
                            break;
                        }
                    }
                    if (className.equals("org.springframework.security.core.authority.SimpleGrantedAuthority")) {
                        if (parameterTypes.length == 1 && parameterTypes[0] == String.class) {
                            creatorConstructor = constructor;
                            paramNames = new String[] { "authority" };
                            break;
                        }
                    }
                    // 
                    boolean is_public = (constructor.getModifiers() & Modifier.PUBLIC) != 0;
                    if (!is_public) {
                        continue;
                    }
                    String[] lookupParameterNames = ASMUtils.lookupParameterNames(constructor);
                    if (lookupParameterNames == null || lookupParameterNames.length == 0) {
                        continue;
                    }
                    if (creatorConstructor != null && paramNames != null && lookupParameterNames.length <= paramNames.length) {
                        continue;
                    }
                    paramNames = lookupParameterNames;
                    creatorConstructor = constructor;
                }
            }
            Class<?>[] types = null;
            if (paramNames != null) {
                types = creatorConstructor.getParameterTypes();
            }
            if (paramNames != null && types.length == paramNames.length) {
                Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
                for (int i = 0; i < types.length; ++i) {
                    Annotation[] paramAnnotations = paramAnnotationArrays[i];
                    String paramName = paramNames[i];
                    JSONField fieldAnnotation = null;
                    for (Annotation paramAnnotation : paramAnnotations) {
                        if (paramAnnotation instanceof JSONField) {
                            fieldAnnotation = (JSONField) paramAnnotation;
                            break;
                        }
                    }
                    Class<?> fieldClass = types[i];
                    Type fieldType = creatorConstructor.getGenericParameterTypes()[i];
                    Field field = TypeUtils.getField(clazz, paramName, declaredFields);
                    if (field != null) {
                        if (fieldAnnotation == null) {
                            fieldAnnotation = field.getAnnotation(JSONField.class);
                        }
                    }
                    final int ordinal, serialzeFeatures, parserFeatures;
                    if (fieldAnnotation == null) {
                        ordinal = 0;
                        serialzeFeatures = 0;
                        if ("org.springframework.security.core.userdetails.User".equals(className) && "password".equals(paramName)) {
                            parserFeatures = Feature.InitStringFieldAsEmpty.mask;
                        } else {
                            parserFeatures = 0;
                        }
                    } else {
                        String nameAnnotated = fieldAnnotation.name();
                        if (nameAnnotated.length() != 0) {
                            paramName = nameAnnotated;
                        }
                        ordinal = fieldAnnotation.ordinal();
                        serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                        parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                    }
                    FieldInfo fieldInfo = new FieldInfo(paramName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures);
                    add(fieldList, fieldInfo);
                }
                if ((!kotlin) && !clazz.getName().equals("javax.servlet.http.Cookie")) {
                    return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList);
                }
            } else {
                throw new JSONException("default constructor not found. " + clazz);
            }
        }
    }
    if (defaultConstructor != null) {
        TypeUtils.setAccessible(defaultConstructor);
    }
    if (builderClass != null) {
        String withPrefix = null;
        JSONPOJOBuilder builderAnno = builderClass.getAnnotation(JSONPOJOBuilder.class);
        if (builderAnno != null) {
            withPrefix = builderAnno.withPrefix();
        }
        if (withPrefix == null || withPrefix.length() == 0) {
            withPrefix = "with";
        }
        for (Method method : builderClass.getMethods()) {
            if (Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            if (!(method.getReturnType().equals(builderClass))) {
                continue;
            }
            int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
            JSONField annotation = method.getAnnotation(JSONField.class);
            if (annotation == null) {
                annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);
            }
            if (annotation != null) {
                if (!annotation.deserialize()) {
                    continue;
                }
                ordinal = annotation.ordinal();
                serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
                parserFeatures = Feature.of(annotation.parseFeatures());
                if (annotation.name().length() != 0) {
                    String propertyName = annotation.name();
                    add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null));
                    continue;
                }
            }
            String methodName = method.getName();
            StringBuilder properNameBuilder;
            if (methodName.startsWith("set") && methodName.length() > 3) {
                properNameBuilder = new StringBuilder(methodName.substring(3));
            } else {
                if (!methodName.startsWith(withPrefix)) {
                    continue;
                }
                if (methodName.length() <= withPrefix.length()) {
                    continue;
                }
                properNameBuilder = new StringBuilder(methodName.substring(withPrefix.length()));
            }
            char c0 = properNameBuilder.charAt(0);
            if (!Character.isUpperCase(c0)) {
                continue;
            }
            properNameBuilder.setCharAt(0, Character.toLowerCase(c0));
            String propertyName = properNameBuilder.toString();
            add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null));
        }
        if (builderClass != null) {
            JSONPOJOBuilder builderAnnotation = builderClass.getAnnotation(JSONPOJOBuilder.class);
            String buildMethodName = null;
            if (builderAnnotation != null) {
                buildMethodName = builderAnnotation.buildMethod();
            }
            if (buildMethodName == null || buildMethodName.length() == 0) {
                buildMethodName = "build";
            }
            try {
                buildMethod = builderClass.getMethod(buildMethodName);
            } catch (NoSuchMethodException e) {
            // skip
            } catch (SecurityException e) {
            // skip
            }
            if (buildMethod == null) {
                try {
                    buildMethod = builderClass.getMethod("create");
                } catch (NoSuchMethodException e) {
                // skip
                } catch (SecurityException e) {
                // skip
                }
            }
            if (buildMethod == null) {
                throw new JSONException("buildMethod not found.");
            }
            TypeUtils.setAccessible(buildMethod);
        }
    }
    for (Method method : methods) {
        // 
        int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
        String methodName = method.getName();
        if (Modifier.isStatic(method.getModifiers())) {
            continue;
        }
        // support builder set
        Class<?> returnType = method.getReturnType();
        if (!(returnType.equals(Void.TYPE) || returnType.equals(method.getDeclaringClass()))) {
            continue;
        }
        if (method.getDeclaringClass() == Object.class) {
            continue;
        }
        Class<?>[] types = method.getParameterTypes();
        if (types.length == 0 || types.length > 2) {
            continue;
        }
        JSONField annotation = method.getAnnotation(JSONField.class);
        if (annotation != null && types.length == 2 && types[0] == String.class && types[1] == Object.class) {
            add(fieldList, new FieldInfo("", method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null));
            continue;
        }
        if (types.length != 1) {
            continue;
        }
        if (annotation == null) {
            annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);
        }
        if (annotation == null && methodName.length() < 4) {
            continue;
        }
        if (annotation != null) {
            if (!annotation.deserialize()) {
                continue;
            }
            ordinal = annotation.ordinal();
            serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
            parserFeatures = Feature.of(annotation.parseFeatures());
            if (annotation.name().length() != 0) {
                String propertyName = annotation.name();
                add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null));
                continue;
            }
        }
        if (annotation == null && !methodName.startsWith("set")) {
            // TODO "set"的判断放在 JSONField 注解后面,意思是允许非 setter 方法标记 JSONField 注解?
            continue;
        }
        char c3 = methodName.charAt(3);
        String propertyName;
        if (// 
        Character.isUpperCase(c3) || // for unicode method name
        c3 > 512) {
            if (TypeUtils.compatibleWithJavaBean) {
                propertyName = TypeUtils.decapitalize(methodName.substring(3));
            } else {
                propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
            }
        } else if (c3 == '_') {
            propertyName = methodName.substring(4);
        } else if (c3 == 'f') {
            propertyName = methodName.substring(3);
        } else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) {
            propertyName = TypeUtils.decapitalize(methodName.substring(3));
        } else {
            continue;
        }
        Field field = TypeUtils.getField(clazz, propertyName, declaredFields);
        if (field == null && types[0] == boolean.class) {
            String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
            field = TypeUtils.getField(clazz, isFieldName, declaredFields);
        }
        JSONField fieldAnnotation = null;
        if (field != null) {
            fieldAnnotation = field.getAnnotation(JSONField.class);
            if (fieldAnnotation != null) {
                if (!fieldAnnotation.deserialize()) {
                    continue;
                }
                ordinal = fieldAnnotation.ordinal();
                serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                if (fieldAnnotation.name().length() != 0) {
                    propertyName = fieldAnnotation.name();
                    add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null));
                    continue;
                }
            }
        }
        if (propertyNamingStrategy != null) {
            propertyName = propertyNamingStrategy.translate(propertyName);
        }
        add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null));
    }
    Field[] fields = clazz.getFields();
    computeFields(clazz, type, propertyNamingStrategy, fieldList, fields);
    for (Method method : clazz.getMethods()) {
        // getter methods
        String methodName = method.getName();
        if (methodName.length() < 4) {
            continue;
        }
        if (Modifier.isStatic(method.getModifiers())) {
            continue;
        }
        if (builderClass == null && methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3))) {
            if (method.getParameterTypes().length != 0) {
                continue;
            }
            if (// 
            Collection.class.isAssignableFrom(method.getReturnType()) || // 
            Map.class.isAssignableFrom(method.getReturnType()) || // 
            AtomicBoolean.class == method.getReturnType() || // 
            AtomicInteger.class == method.getReturnType() || // 
            AtomicLong.class == method.getReturnType()) {
                String propertyName;
                JSONField annotation = method.getAnnotation(JSONField.class);
                if (annotation != null && annotation.deserialize()) {
                    continue;
                }
                if (annotation != null && annotation.name().length() > 0) {
                    propertyName = annotation.name();
                } else {
                    propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
                    Field field = TypeUtils.getField(clazz, propertyName, declaredFields);
                    if (field != null) {
                        JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
                        if (fieldAnnotation != null && !fieldAnnotation.deserialize()) {
                            continue;
                        }
                    }
                }
                if (propertyNamingStrategy != null) {
                    propertyName = propertyNamingStrategy.translate(propertyName);
                }
                FieldInfo fieldInfo = getField(fieldList, propertyName);
                if (fieldInfo != null) {
                    continue;
                }
                add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, 0, 0, 0, annotation, null, null));
            }
        }
    }
    if (fieldList.size() == 0) {
        XmlAccessorType accessorType = clazz.getAnnotation(XmlAccessorType.class);
        if (accessorType != null && accessorType.value() == XmlAccessType.FIELD) {
            fieldBased = true;
        }
        if (fieldBased) {
            for (Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) {
                computeFields(clazz, type, propertyNamingStrategy, fieldList, declaredFields);
            }
        }
    }
    return new JavaBeanInfo(clazz, builderClass, defaultConstructor, creatorConstructor, factoryMethod, buildMethod, jsonType, fieldList);
}
Also used : JSONPOJOBuilder(com.alibaba.fastjson.annotation.JSONPOJOBuilder) JSONField(com.alibaba.fastjson.annotation.JSONField) JSONField(com.alibaba.fastjson.annotation.JSONField) Field(java.lang.reflect.Field) Constructor(java.lang.reflect.Constructor) JSONException(com.alibaba.fastjson.JSONException) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) XmlAccessorType(javax.xml.bind.annotation.XmlAccessorType) XmlAccessType(javax.xml.bind.annotation.XmlAccessType) Type(java.lang.reflect.Type) JSONType(com.alibaba.fastjson.annotation.JSONType) AtomicLong(java.util.concurrent.atomic.AtomicLong) XmlAccessorType(javax.xml.bind.annotation.XmlAccessorType) PropertyNamingStrategy(com.alibaba.fastjson.PropertyNamingStrategy) JSONType(com.alibaba.fastjson.annotation.JSONType)

Example 2 with PropertyNamingStrategy

use of com.alibaba.fastjson.PropertyNamingStrategy in project fastjson by alibaba.

the class TypeUtils method buildBeanInfo.

public static // 
SerializeBeanInfo buildBeanInfo(// 
Class<?> beanType, // 
Map<String, String> aliasMap, // 
PropertyNamingStrategy propertyNamingStrategy, // 
boolean fieldBased) {
    JSONType jsonType = TypeUtils.getAnnotation(beanType, JSONType.class);
    String[] orders = null;
    final int features;
    String typeName = null, typeKey = null;
    if (jsonType != null) {
        orders = jsonType.orders();
        typeName = jsonType.typeName();
        if (typeName.length() == 0) {
            typeName = null;
        }
        PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
        if (jsonTypeNaming != PropertyNamingStrategy.NeverUseThisValueExceptDefaultValue) {
            propertyNamingStrategy = jsonTypeNaming;
        }
        features = SerializerFeature.of(jsonType.serialzeFeatures());
        for (Class<?> supperClass = beanType.getSuperclass(); supperClass != null && supperClass != Object.class; supperClass = supperClass.getSuperclass()) {
            JSONType superJsonType = TypeUtils.getAnnotation(supperClass, JSONType.class);
            if (superJsonType == null) {
                break;
            }
            typeKey = superJsonType.typeKey();
            if (typeKey.length() != 0) {
                break;
            }
        }
        for (Class<?> interfaceClass : beanType.getInterfaces()) {
            JSONType superJsonType = TypeUtils.getAnnotation(interfaceClass, JSONType.class);
            if (superJsonType != null) {
                typeKey = superJsonType.typeKey();
                if (typeKey.length() != 0) {
                    break;
                }
            }
        }
        if (typeKey != null && typeKey.length() == 0) {
            typeKey = null;
        }
    } else {
        features = 0;
    }
    // fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询
    Map<String, Field> fieldCacheMap = new HashMap<String, Field>();
    ParserConfig.parserAllFieldToCache(beanType, fieldCacheMap);
    List<FieldInfo> fieldInfoList = fieldBased ? // 
    computeGettersWithFieldBase(beanType, aliasMap, false, propertyNamingStrategy) : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, false, propertyNamingStrategy);
    FieldInfo[] fields = new FieldInfo[fieldInfoList.size()];
    fieldInfoList.toArray(fields);
    FieldInfo[] sortedFields;
    List<FieldInfo> sortedFieldList;
    if (orders != null && orders.length != 0) {
        sortedFieldList = fieldBased ? // 
        computeGettersWithFieldBase(beanType, aliasMap, true, propertyNamingStrategy) : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, true, propertyNamingStrategy);
    } else {
        sortedFieldList = new ArrayList<FieldInfo>(fieldInfoList);
        Collections.sort(sortedFieldList);
    }
    sortedFields = new FieldInfo[sortedFieldList.size()];
    sortedFieldList.toArray(sortedFields);
    if (Arrays.equals(sortedFields, fields)) {
        sortedFields = fields;
    }
    return new SerializeBeanInfo(beanType, jsonType, typeName, typeKey, features, fields, sortedFields);
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) JSONField(com.alibaba.fastjson.annotation.JSONField) SerializeBeanInfo(com.alibaba.fastjson.serializer.SerializeBeanInfo) PropertyNamingStrategy(com.alibaba.fastjson.PropertyNamingStrategy) JSONObject(com.alibaba.fastjson.JSONObject) JSONType(com.alibaba.fastjson.annotation.JSONType)

Example 3 with PropertyNamingStrategy

use of com.alibaba.fastjson.PropertyNamingStrategy in project fastjson by alibaba.

the class JavaBeanInfo method build.

public static // 
JavaBeanInfo build(// 
Class<?> clazz, // 
Type type, // 
PropertyNamingStrategy propertyNamingStrategy, // 
boolean fieldBased, boolean compatibleWithJavaBean, boolean jacksonCompatible) {
    JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
    if (jsonType != null) {
        PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
        if (jsonTypeNaming != null && jsonTypeNaming != PropertyNamingStrategy.CamelCase) {
            propertyNamingStrategy = jsonTypeNaming;
        }
    }
    Class<?> builderClass = getBuilderClass(clazz, jsonType);
    Field[] declaredFields = clazz.getDeclaredFields();
    Method[] methods = clazz.getMethods();
    Map<TypeVariable, Type> genericInfo = buildGenericInfo(clazz);
    boolean kotlin = TypeUtils.isKotlin(clazz);
    Constructor[] constructors = clazz.getDeclaredConstructors();
    Constructor<?> defaultConstructor = null;
    if ((!kotlin) || constructors.length == 1) {
        if (builderClass == null) {
            defaultConstructor = getDefaultConstructor(clazz, constructors);
        } else {
            defaultConstructor = getDefaultConstructor(builderClass, builderClass.getDeclaredConstructors());
        }
    }
    Constructor<?> creatorConstructor = null;
    Method buildMethod = null;
    Method factoryMethod = null;
    List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
    if (fieldBased) {
        for (Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) {
            Field[] fields = currentClass.getDeclaredFields();
            computeFields(clazz, type, propertyNamingStrategy, fieldList, fields);
        }
        if (defaultConstructor != null) {
            TypeUtils.setAccessible(defaultConstructor);
        }
        return new JavaBeanInfo(clazz, builderClass, defaultConstructor, null, factoryMethod, buildMethod, jsonType, fieldList);
    }
    boolean isInterfaceOrAbstract = clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers());
    if ((defaultConstructor == null && builderClass == null) || isInterfaceOrAbstract) {
        Type mixInType = JSON.getMixInAnnotations(clazz);
        if (mixInType instanceof Class) {
            Constructor<?>[] mixInConstructors = ((Class<?>) mixInType).getConstructors();
            Constructor<?> mixInCreator = getCreatorConstructor(mixInConstructors);
            if (mixInCreator != null) {
                try {
                    creatorConstructor = clazz.getConstructor(mixInCreator.getParameterTypes());
                } catch (NoSuchMethodException e) {
                // skip
                }
            }
        }
        if (creatorConstructor == null) {
            creatorConstructor = getCreatorConstructor(constructors);
        }
        if (creatorConstructor != null && !isInterfaceOrAbstract) {
            // 基于标记 JSONCreator 注解的构造方法
            TypeUtils.setAccessible(creatorConstructor);
            Class<?>[] types = creatorConstructor.getParameterTypes();
            String[] lookupParameterNames = null;
            if (types.length > 0) {
                Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor);
                for (int i = 0; i < types.length && i < paramAnnotationArrays.length; ++i) {
                    Annotation[] paramAnnotations = paramAnnotationArrays[i];
                    JSONField fieldAnnotation = null;
                    for (Annotation paramAnnotation : paramAnnotations) {
                        if (paramAnnotation instanceof JSONField) {
                            fieldAnnotation = (JSONField) paramAnnotation;
                            break;
                        }
                    }
                    Class<?> fieldClass = types[i];
                    Type fieldType = creatorConstructor.getGenericParameterTypes()[i];
                    String fieldName = null;
                    Field field = null;
                    int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
                    if (fieldAnnotation != null) {
                        field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields);
                        ordinal = fieldAnnotation.ordinal();
                        serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                        parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                        fieldName = fieldAnnotation.name();
                    }
                    if (fieldName == null || fieldName.length() == 0) {
                        if (lookupParameterNames == null) {
                            lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor);
                        }
                        fieldName = lookupParameterNames[i];
                    }
                    if (field == null) {
                        if (lookupParameterNames == null) {
                            if (kotlin) {
                                lookupParameterNames = TypeUtils.getKoltinConstructorParameters(clazz);
                            } else {
                                lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor);
                            }
                        }
                        if (lookupParameterNames.length > i) {
                            String parameterName = lookupParameterNames[i];
                            field = TypeUtils.getField(clazz, parameterName, declaredFields);
                        }
                    }
                    FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures);
                    add(fieldList, fieldInfo);
                }
            }
        // return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList);
        } else if ((factoryMethod = getFactoryMethod(clazz, methods, jacksonCompatible)) != null) {
            TypeUtils.setAccessible(factoryMethod);
            String[] lookupParameterNames = null;
            Class<?>[] types = factoryMethod.getParameterTypes();
            if (types.length > 0) {
                Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(factoryMethod);
                for (int i = 0; i < types.length; ++i) {
                    Annotation[] paramAnnotations = paramAnnotationArrays[i];
                    JSONField fieldAnnotation = null;
                    for (Annotation paramAnnotation : paramAnnotations) {
                        if (paramAnnotation instanceof JSONField) {
                            fieldAnnotation = (JSONField) paramAnnotation;
                            break;
                        }
                    }
                    if (fieldAnnotation == null && !(jacksonCompatible && TypeUtils.isJacksonCreator(factoryMethod))) {
                        throw new JSONException("illegal json creator");
                    }
                    String fieldName = null;
                    int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
                    if (fieldAnnotation != null) {
                        fieldName = fieldAnnotation.name();
                        ordinal = fieldAnnotation.ordinal();
                        serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                        parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                    }
                    if (fieldName == null || fieldName.length() == 0) {
                        if (lookupParameterNames == null) {
                            lookupParameterNames = ASMUtils.lookupParameterNames(factoryMethod);
                        }
                        fieldName = lookupParameterNames[i];
                    }
                    Class<?> fieldClass = types[i];
                    Type fieldType = factoryMethod.getGenericParameterTypes()[i];
                    Field field = TypeUtils.getField(clazz, fieldName, declaredFields);
                    FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures);
                    add(fieldList, fieldInfo);
                }
                return new JavaBeanInfo(clazz, builderClass, null, null, factoryMethod, null, jsonType, fieldList);
            }
        } else if (!isInterfaceOrAbstract) {
            String className = clazz.getName();
            String[] paramNames = null;
            if (kotlin && constructors.length > 0) {
                paramNames = TypeUtils.getKoltinConstructorParameters(clazz);
                creatorConstructor = TypeUtils.getKotlinConstructor(constructors, paramNames);
                TypeUtils.setAccessible(creatorConstructor);
            } else {
                for (Constructor constructor : constructors) {
                    Class<?>[] parameterTypes = constructor.getParameterTypes();
                    if (className.equals("org.springframework.security.web.authentication.WebAuthenticationDetails")) {
                        if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) {
                            creatorConstructor = constructor;
                            creatorConstructor.setAccessible(true);
                            paramNames = ASMUtils.lookupParameterNames(constructor);
                            break;
                        } else {
                            continue;
                        }
                    }
                    if (className.equals("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken")) {
                        if (parameterTypes.length == 3 && parameterTypes[0] == Object.class && parameterTypes[1] == Object.class && parameterTypes[2] == Collection.class) {
                            creatorConstructor = constructor;
                            creatorConstructor.setAccessible(true);
                            paramNames = new String[] { "principal", "credentials", "authorities" };
                            break;
                        } else {
                            continue;
                        }
                    }
                    if (className.equals("org.springframework.security.core.authority.SimpleGrantedAuthority")) {
                        if (parameterTypes.length == 1 && parameterTypes[0] == String.class) {
                            creatorConstructor = constructor;
                            paramNames = new String[] { "authority" };
                            break;
                        } else {
                            continue;
                        }
                    }
                    // 
                    boolean is_public = (constructor.getModifiers() & Modifier.PUBLIC) != 0;
                    if (!is_public) {
                        continue;
                    }
                    String[] lookupParameterNames = ASMUtils.lookupParameterNames(constructor);
                    if (lookupParameterNames == null || lookupParameterNames.length == 0) {
                        continue;
                    }
                    if (creatorConstructor != null && paramNames != null && lookupParameterNames.length <= paramNames.length) {
                        continue;
                    }
                    paramNames = lookupParameterNames;
                    creatorConstructor = constructor;
                }
            }
            Class<?>[] types = null;
            if (paramNames != null) {
                types = creatorConstructor.getParameterTypes();
            }
            if (paramNames != null && types.length == paramNames.length) {
                Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor);
                for (int i = 0; i < types.length; ++i) {
                    Annotation[] paramAnnotations = paramAnnotationArrays[i];
                    String paramName = paramNames[i];
                    JSONField fieldAnnotation = null;
                    for (Annotation paramAnnotation : paramAnnotations) {
                        if (paramAnnotation instanceof JSONField) {
                            fieldAnnotation = (JSONField) paramAnnotation;
                            break;
                        }
                    }
                    Class<?> fieldClass = types[i];
                    Type fieldType = creatorConstructor.getGenericParameterTypes()[i];
                    Field field = TypeUtils.getField(clazz, paramName, declaredFields);
                    if (field != null) {
                        if (fieldAnnotation == null) {
                            fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
                        }
                    }
                    final int ordinal, serialzeFeatures, parserFeatures;
                    if (fieldAnnotation == null) {
                        ordinal = 0;
                        serialzeFeatures = 0;
                        if ("org.springframework.security.core.userdetails.User".equals(className) && "password".equals(paramName)) {
                            parserFeatures = Feature.InitStringFieldAsEmpty.mask;
                        } else {
                            parserFeatures = 0;
                        }
                    } else {
                        String nameAnnotated = fieldAnnotation.name();
                        if (nameAnnotated.length() != 0) {
                            paramName = nameAnnotated;
                        }
                        ordinal = fieldAnnotation.ordinal();
                        serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                        parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                    }
                    FieldInfo fieldInfo = new FieldInfo(paramName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures);
                    add(fieldList, fieldInfo);
                }
                if ((!kotlin) && !clazz.getName().equals("javax.servlet.http.Cookie")) {
                    return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList);
                }
            } else {
                throw new JSONException("default constructor not found. " + clazz);
            }
        }
    }
    if (defaultConstructor != null) {
        TypeUtils.setAccessible(defaultConstructor);
    }
    if (builderClass != null) {
        String withPrefix = null;
        JSONPOJOBuilder builderAnno = TypeUtils.getAnnotation(builderClass, JSONPOJOBuilder.class);
        if (builderAnno != null) {
            withPrefix = builderAnno.withPrefix();
        }
        if (withPrefix == null) {
            withPrefix = "with";
        }
        for (Method method : builderClass.getMethods()) {
            if (Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            if (!(method.getReturnType().equals(builderClass))) {
                continue;
            }
            int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
            JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class);
            if (annotation == null) {
                annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);
            }
            if (annotation != null) {
                if (!annotation.deserialize()) {
                    continue;
                }
                ordinal = annotation.ordinal();
                serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
                parserFeatures = Feature.of(annotation.parseFeatures());
                if (annotation.name().length() != 0) {
                    String propertyName = annotation.name();
                    add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null, genericInfo));
                    continue;
                }
            }
            String methodName = method.getName();
            StringBuilder properNameBuilder;
            if (methodName.startsWith("set") && methodName.length() > 3) {
                properNameBuilder = new StringBuilder(methodName.substring(3));
            } else {
                if (withPrefix.length() == 0) {
                    properNameBuilder = new StringBuilder(methodName);
                } else {
                    if (!methodName.startsWith(withPrefix)) {
                        continue;
                    }
                    if (methodName.length() <= withPrefix.length()) {
                        continue;
                    }
                    properNameBuilder = new StringBuilder(methodName.substring(withPrefix.length()));
                }
            }
            char c0 = properNameBuilder.charAt(0);
            if (withPrefix.length() != 0 && !Character.isUpperCase(c0)) {
                continue;
            }
            properNameBuilder.setCharAt(0, Character.toLowerCase(c0));
            String propertyName = properNameBuilder.toString();
            add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null, genericInfo));
        }
        if (builderClass != null) {
            JSONPOJOBuilder builderAnnotation = TypeUtils.getAnnotation(builderClass, JSONPOJOBuilder.class);
            String buildMethodName = null;
            if (builderAnnotation != null) {
                buildMethodName = builderAnnotation.buildMethod();
            }
            if (buildMethodName == null || buildMethodName.length() == 0) {
                buildMethodName = "build";
            }
            try {
                buildMethod = builderClass.getMethod(buildMethodName);
            } catch (NoSuchMethodException e) {
            // skip
            } catch (SecurityException e) {
            // skip
            }
            if (buildMethod == null) {
                try {
                    buildMethod = builderClass.getMethod("create");
                } catch (NoSuchMethodException e) {
                // skip
                } catch (SecurityException e) {
                // skip
                }
            }
            if (buildMethod == null) {
                throw new JSONException("buildMethod not found.");
            }
            TypeUtils.setAccessible(buildMethod);
        }
    }
    for (Method method : methods) {
        // 
        int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
        String methodName = method.getName();
        if (Modifier.isStatic(method.getModifiers())) {
            continue;
        }
        // support builder set
        Class<?> returnType = method.getReturnType();
        if (!(returnType.equals(Void.TYPE) || returnType.equals(method.getDeclaringClass()))) {
            continue;
        }
        if (method.getDeclaringClass() == Object.class) {
            continue;
        }
        Class<?>[] types = method.getParameterTypes();
        if (types.length == 0 || types.length > 2) {
            continue;
        }
        JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class);
        if (annotation != null && types.length == 2 && types[0] == String.class && types[1] == Object.class) {
            add(fieldList, new FieldInfo("", method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null, genericInfo));
            continue;
        }
        if (types.length != 1) {
            continue;
        }
        if (annotation == null) {
            annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);
        }
        if (annotation == null && methodName.length() < 4) {
            continue;
        }
        if (annotation != null) {
            if (!annotation.deserialize()) {
                continue;
            }
            ordinal = annotation.ordinal();
            serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
            parserFeatures = Feature.of(annotation.parseFeatures());
            if (annotation.name().length() != 0) {
                String propertyName = annotation.name();
                add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null, genericInfo));
                continue;
            }
        }
        if (annotation == null && !methodName.startsWith("set") || builderClass != null) {
            // TODO "set"的判断放在 JSONField 注解后面,意思是允许非 setter 方法标记 JSONField 注解?
            continue;
        }
        char c3 = methodName.charAt(3);
        String propertyName;
        Field field = null;
        // 用于存储KotlinBean中所有的get方法, 方便后续判断
        List<String> getMethodNameList = null;
        if (kotlin) {
            getMethodNameList = new ArrayList();
            for (int i = 0; i < methods.length; i++) {
                if (methods[i].getName().startsWith("get")) {
                    getMethodNameList.add(methods[i].getName());
                }
            }
        }
        if (// 
        Character.isUpperCase(c3) || // for unicode method name
        c3 > 512) {
            // 因此如果是kotlin的话还需要进行不一样的判断, 判断的方式是通过get方法进行判断, isAbc的get方法名为isAbc(), abc的get方法名为getAbc()
            if (kotlin) {
                String getMethodName = "g" + methodName.substring(1);
                propertyName = TypeUtils.getPropertyNameByMethodName(getMethodName);
            } else {
                if (TypeUtils.compatibleWithJavaBean) {
                    propertyName = TypeUtils.decapitalize(methodName.substring(3));
                } else {
                    propertyName = TypeUtils.getPropertyNameByMethodName(methodName);
                }
            }
        } else if (c3 == '_') {
            // 因此如果是kotlin的话还需要进行不一样的判断, 判断的方式是通过get方法进行判断, is_abc的get方法名为is_abc(), _abc的get方法名为get_abc()
            if (kotlin) {
                String getMethodName = "g" + methodName.substring(1);
                if (getMethodNameList.contains(getMethodName)) {
                    propertyName = methodName.substring(3);
                } else {
                    propertyName = "is" + methodName.substring(3);
                }
                field = TypeUtils.getField(clazz, propertyName, declaredFields);
            } else {
                propertyName = methodName.substring(4);
                field = TypeUtils.getField(clazz, propertyName, declaredFields);
                if (field == null) {
                    String temp = propertyName;
                    propertyName = methodName.substring(3);
                    field = TypeUtils.getField(clazz, propertyName, declaredFields);
                    if (field == null) {
                        // 减少修改代码带来的影响
                        propertyName = temp;
                    }
                }
            }
        } else if (c3 == 'f') {
            propertyName = methodName.substring(3);
        } else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) {
            propertyName = TypeUtils.decapitalize(methodName.substring(3));
        } else {
            propertyName = methodName.substring(3);
            field = TypeUtils.getField(clazz, propertyName, declaredFields);
            if (field == null) {
                continue;
            }
        }
        if (field == null) {
            field = TypeUtils.getField(clazz, propertyName, declaredFields);
        }
        if (field == null && types[0] == boolean.class) {
            String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
            field = TypeUtils.getField(clazz, isFieldName, declaredFields);
        }
        JSONField fieldAnnotation = null;
        if (field != null) {
            fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
            if (fieldAnnotation != null) {
                if (!fieldAnnotation.deserialize()) {
                    continue;
                }
                ordinal = fieldAnnotation.ordinal();
                serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
                parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
                if (fieldAnnotation.name().length() != 0) {
                    propertyName = fieldAnnotation.name();
                    add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null, genericInfo));
                    continue;
                }
            }
        }
        if (propertyNamingStrategy != null) {
            propertyName = propertyNamingStrategy.translate(propertyName);
        }
        add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null, genericInfo));
    }
    Field[] fields = clazz.getFields();
    computeFields(clazz, type, propertyNamingStrategy, fieldList, fields);
    for (Method method : clazz.getMethods()) {
        // getter methods
        String methodName = method.getName();
        if (methodName.length() < 4) {
            continue;
        }
        if (Modifier.isStatic(method.getModifiers())) {
            continue;
        }
        if (builderClass == null && methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3))) {
            if (method.getParameterTypes().length != 0) {
                continue;
            }
            if (// 
            Collection.class.isAssignableFrom(method.getReturnType()) || // 
            Map.class.isAssignableFrom(method.getReturnType()) || // 
            AtomicBoolean.class == method.getReturnType() || // 
            AtomicInteger.class == method.getReturnType() || // 
            AtomicLong.class == method.getReturnType()) {
                String propertyName;
                Field collectionField = null;
                JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class);
                if (annotation != null && annotation.deserialize()) {
                    continue;
                }
                if (annotation != null && annotation.name().length() > 0) {
                    propertyName = annotation.name();
                } else {
                    propertyName = TypeUtils.getPropertyNameByMethodName(methodName);
                    Field field = TypeUtils.getField(clazz, propertyName, declaredFields);
                    if (field != null) {
                        JSONField fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
                        if (fieldAnnotation != null && !fieldAnnotation.deserialize()) {
                            continue;
                        }
                        if (Collection.class.isAssignableFrom(method.getReturnType()) || Map.class.isAssignableFrom(method.getReturnType())) {
                            collectionField = field;
                        }
                    }
                }
                if (propertyNamingStrategy != null) {
                    propertyName = propertyNamingStrategy.translate(propertyName);
                }
                FieldInfo fieldInfo = getField(fieldList, propertyName);
                if (fieldInfo != null) {
                    continue;
                }
                add(fieldList, new FieldInfo(propertyName, method, collectionField, clazz, type, 0, 0, 0, annotation, null, null, genericInfo));
            }
        }
    }
    if (fieldList.size() == 0) {
        if (TypeUtils.isXmlField(clazz)) {
            fieldBased = true;
        }
        if (fieldBased) {
            for (Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) {
                computeFields(clazz, type, propertyNamingStrategy, fieldList, declaredFields);
            }
        }
    }
    return new JavaBeanInfo(clazz, builderClass, defaultConstructor, creatorConstructor, factoryMethod, buildMethod, jsonType, fieldList);
}
Also used : JSONPOJOBuilder(com.alibaba.fastjson.annotation.JSONPOJOBuilder) JSONField(com.alibaba.fastjson.annotation.JSONField) JSONField(com.alibaba.fastjson.annotation.JSONField) JSONException(com.alibaba.fastjson.JSONException) Annotation(java.lang.annotation.Annotation) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JSONType(com.alibaba.fastjson.annotation.JSONType) AtomicLong(java.util.concurrent.atomic.AtomicLong) PropertyNamingStrategy(com.alibaba.fastjson.PropertyNamingStrategy) JSONType(com.alibaba.fastjson.annotation.JSONType)

Example 4 with PropertyNamingStrategy

use of com.alibaba.fastjson.PropertyNamingStrategy in project uavstack by uavorg.

the class TypeUtils method buildBeanInfo.

public static // 
SerializeBeanInfo buildBeanInfo(// 
Class<?> beanType, // 
Map<String, String> aliasMap, // 
PropertyNamingStrategy propertyNamingStrategy, // 
boolean fieldBased) {
    JSONType jsonType = TypeUtils.getAnnotation(beanType, JSONType.class);
    String[] orders = null;
    final int features;
    String typeName = null, typeKey = null;
    if (jsonType != null) {
        orders = jsonType.orders();
        typeName = jsonType.typeName();
        if (typeName.length() == 0) {
            typeName = null;
        }
        PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
        if (jsonTypeNaming != PropertyNamingStrategy.CamelCase) {
            propertyNamingStrategy = jsonTypeNaming;
        }
        features = SerializerFeature.of(jsonType.serialzeFeatures());
        for (Class<?> supperClass = beanType.getSuperclass(); supperClass != null && supperClass != Object.class; supperClass = supperClass.getSuperclass()) {
            JSONType superJsonType = TypeUtils.getAnnotation(supperClass, JSONType.class);
            if (superJsonType == null) {
                break;
            }
            typeKey = superJsonType.typeKey();
            if (typeKey.length() != 0) {
                break;
            }
        }
        for (Class<?> interfaceClass : beanType.getInterfaces()) {
            JSONType superJsonType = TypeUtils.getAnnotation(interfaceClass, JSONType.class);
            if (superJsonType != null) {
                typeKey = superJsonType.typeKey();
                if (typeKey.length() != 0) {
                    break;
                }
            }
        }
        if (typeKey != null && typeKey.length() == 0) {
            typeKey = null;
        }
    } else {
        features = 0;
    }
    // fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询
    Map<String, Field> fieldCacheMap = new HashMap<String, Field>();
    ParserConfig.parserAllFieldToCache(beanType, fieldCacheMap);
    List<FieldInfo> fieldInfoList = fieldBased ? // 
    computeGettersWithFieldBase(beanType, aliasMap, false, propertyNamingStrategy) : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, false, propertyNamingStrategy);
    FieldInfo[] fields = new FieldInfo[fieldInfoList.size()];
    fieldInfoList.toArray(fields);
    FieldInfo[] sortedFields;
    List<FieldInfo> sortedFieldList;
    if (orders != null && orders.length != 0) {
        sortedFieldList = fieldBased ? // 
        computeGettersWithFieldBase(beanType, aliasMap, true, propertyNamingStrategy) : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, true, propertyNamingStrategy);
    } else {
        sortedFieldList = new ArrayList<FieldInfo>(fieldInfoList);
        Collections.sort(sortedFieldList);
    }
    sortedFields = new FieldInfo[sortedFieldList.size()];
    sortedFieldList.toArray(sortedFields);
    if (Arrays.equals(sortedFields, fields)) {
        sortedFields = fields;
    }
    return new SerializeBeanInfo(beanType, jsonType, typeName, typeKey, features, fields, sortedFields);
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) JSONField(com.alibaba.fastjson.annotation.JSONField) Field(java.lang.reflect.Field) SerializeBeanInfo(com.alibaba.fastjson.serializer.SerializeBeanInfo) PropertyNamingStrategy(com.alibaba.fastjson.PropertyNamingStrategy) JSONObject(com.alibaba.fastjson.JSONObject) AccessibleObject(java.lang.reflect.AccessibleObject) JSONType(com.alibaba.fastjson.annotation.JSONType)

Aggregations

PropertyNamingStrategy (com.alibaba.fastjson.PropertyNamingStrategy)4 JSONField (com.alibaba.fastjson.annotation.JSONField)4 JSONType (com.alibaba.fastjson.annotation.JSONType)4 JSONException (com.alibaba.fastjson.JSONException)2 JSONObject (com.alibaba.fastjson.JSONObject)2 JSONPOJOBuilder (com.alibaba.fastjson.annotation.JSONPOJOBuilder)2 SerializeBeanInfo (com.alibaba.fastjson.serializer.SerializeBeanInfo)2 Annotation (java.lang.annotation.Annotation)2 Field (java.lang.reflect.Field)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 AccessibleObject (java.lang.reflect.AccessibleObject)1 Constructor (java.lang.reflect.Constructor)1 Method (java.lang.reflect.Method)1 Type (java.lang.reflect.Type)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 XmlAccessType (javax.xml.bind.annotation.XmlAccessType)1 XmlAccessorType (javax.xml.bind.annotation.XmlAccessorType)1