/src/main/java/com/alibaba/fastjson/util/DeserializeBeanInfo.java
Java | 357 lines | 288 code | 68 blank | 1 comment | 89 complexity | 73f7880f9a3c7063d3d19f56e9837bc3 MD5 | raw file
- package com.alibaba.fastjson.util;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.lang.reflect.Modifier;
- import java.lang.reflect.Type;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- import com.alibaba.fastjson.JSONException;
- import com.alibaba.fastjson.annotation.JSONCreator;
- import com.alibaba.fastjson.annotation.JSONField;
- public class DeserializeBeanInfo {
- private final Class<?> clazz;
- private final Type type;
- private Constructor<?> defaultConstructor;
- private Constructor<?> creatorConstructor;
- private Method factoryMethod;
- private final List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
- public DeserializeBeanInfo(Class<?> clazz){
- super();
- this.clazz = clazz;
- this.type = clazz;
- }
- public Constructor<?> getDefaultConstructor() {
- return defaultConstructor;
- }
- public void setDefaultConstructor(Constructor<?> defaultConstructor) {
- this.defaultConstructor = defaultConstructor;
- }
- public Constructor<?> getCreatorConstructor() {
- return creatorConstructor;
- }
- public void setCreatorConstructor(Constructor<?> createConstructor) {
- this.creatorConstructor = createConstructor;
- }
- public Method getFactoryMethod() {
- return factoryMethod;
- }
- public void setFactoryMethod(Method factoryMethod) {
- this.factoryMethod = factoryMethod;
- }
- public Class<?> getClazz() {
- return clazz;
- }
- public Type getType() {
- return type;
- }
- public List<FieldInfo> getFieldList() {
- return fieldList;
- }
-
- public FieldInfo getField(String propertyName) {
- for (FieldInfo item : this.fieldList) {
- if (item.getName().equals(propertyName)) {
- return item;
- }
- }
-
- return null;
- }
-
- public boolean add(FieldInfo field) {
- for (FieldInfo item : this.fieldList) {
- if (item.getName().equals(field.getName())) {
- return false;
- }
- }
- fieldList.add(field);
-
- return true;
- }
-
- public static DeserializeBeanInfo computeSetters(Class<?> clazz) {
- return computeSetters(clazz, clazz);
- }
- public static DeserializeBeanInfo computeSetters(Class<?> clazz, Type type) {
- DeserializeBeanInfo beanInfo = new DeserializeBeanInfo(clazz);
- Constructor<?> defaultConstructor = getDefaultConstructor(clazz);
- if (defaultConstructor != null) {
- defaultConstructor.setAccessible(true);
- beanInfo.setDefaultConstructor(defaultConstructor);
- } else if (defaultConstructor == null && !(clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()))) {
- Constructor<?> creatorConstructor = getCreatorConstructor(clazz);
- if (creatorConstructor != null) {
- creatorConstructor.setAccessible(true);
- beanInfo.setCreatorConstructor(creatorConstructor);
- for (int i = 0; i < creatorConstructor.getParameterTypes().length; ++i) {
- Annotation[] paramAnnotations = creatorConstructor.getParameterAnnotations()[i];
- JSONField fieldAnnotation = null;
- for (Annotation paramAnnotation : paramAnnotations) {
- if (paramAnnotation instanceof JSONField) {
- fieldAnnotation = (JSONField) paramAnnotation;
- break;
- }
- }
- if (fieldAnnotation == null) {
- throw new JSONException("illegal json creator");
- }
- Class<?> fieldClass = creatorConstructor.getParameterTypes()[i];
- Type fieldType = creatorConstructor.getGenericParameterTypes()[i];
- Field field = getField(clazz, fieldAnnotation.name());
- if (field != null) {
- field.setAccessible(true);
- }
- FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, null,
- field);
- beanInfo.add(fieldInfo);
- }
- return beanInfo;
- }
- Method factoryMethod = getFactoryMethod(clazz);
- if (factoryMethod != null) {
- factoryMethod.setAccessible(true);
- beanInfo.setFactoryMethod(factoryMethod);
- for (int i = 0; i < factoryMethod.getParameterTypes().length; ++i) {
- Annotation[] paramAnnotations = factoryMethod.getParameterAnnotations()[i];
- JSONField fieldAnnotation = null;
- for (Annotation paramAnnotation : paramAnnotations) {
- if (paramAnnotation instanceof JSONField) {
- fieldAnnotation = (JSONField) paramAnnotation;
- break;
- }
- }
- if (fieldAnnotation == null) {
- throw new JSONException("illegal json creator");
- }
- Class<?> fieldClass = factoryMethod.getParameterTypes()[i];
- Type fieldType = factoryMethod.getGenericParameterTypes()[i];
- Field field = getField(clazz, fieldAnnotation.name());
- if (field != null) {
- field.setAccessible(true);
- }
- FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, null,
- field);
- beanInfo.add(fieldInfo);
- }
- return beanInfo;
- }
-
- throw new JSONException("default constructor not found. " + clazz);
- }
- for (Method method : clazz.getMethods()) {
- String methodName = method.getName();
- if (methodName.length() < 4) {
- continue;
- }
- if (Modifier.isStatic(method.getModifiers())) {
- continue;
- }
- // support builder set
- if (!(method.getReturnType().equals(Void.TYPE) || method.getReturnType().equals(clazz))) {
- continue;
- }
- if (method.getParameterTypes().length != 1) {
- continue;
- }
- JSONField annotation = method.getAnnotation(JSONField.class);
- if (annotation != null) {
- if (!annotation.deserialize()) {
- continue;
- }
- if (annotation.name().length() != 0) {
- String propertyName = annotation.name();
- beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type));
- method.setAccessible(true);
- continue;
- }
- }
- if (methodName.startsWith("set") && Character.isUpperCase(methodName.charAt(3))) {
- String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
- Field field = getField(clazz, propertyName);
- if (field != null) {
- JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
- if (fieldAnnotation != null && fieldAnnotation.name().length() != 0) {
- propertyName = fieldAnnotation.name();
- beanInfo.add(new FieldInfo(propertyName, method, field, clazz, type));
- continue;
- }
- }
- beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type));
- method.setAccessible(true);
- }
- }
- for (Field field : clazz.getFields()) {
- if (Modifier.isStatic(field.getModifiers())) {
- continue;
- }
- if (!Modifier.isPublic(field.getModifiers())) {
- continue;
- }
-
- boolean contains = false;
- for (FieldInfo item : beanInfo.getFieldList()) {
- if (item.getName().equals(field.getName())) {
- contains = true;
- continue;
- }
- }
-
- if (contains) {
- continue;
- }
- beanInfo.add(new FieldInfo(field.getName(), null, field));
- }
-
- for (Method method : clazz.getMethods()) {
- String methodName = method.getName();
- if (methodName.length() < 4) {
- continue;
- }
- if (Modifier.isStatic(method.getModifiers())) {
- continue;
- }
-
- if (methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3))) {
- if (method.getParameterTypes().length != 0) {
- continue;
- }
-
- if (!Collection.class.isAssignableFrom(method.getReturnType())) {
- continue;
- }
-
- String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
-
- FieldInfo fieldInfo = beanInfo.getField(propertyName);
- if (fieldInfo != null) {
- continue;
- }
-
- beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type));
- method.setAccessible(true);
- }
- }
- return beanInfo;
- }
- public static Field getField(Class<?> clazz, String fieldName) {
- try {
- return clazz.getDeclaredField(fieldName);
- } catch (Exception e) {
- return null;
- }
- }
- public static Constructor<?> getDefaultConstructor(Class<?> clazz) {
- if (Modifier.isAbstract(clazz.getModifiers())) {
- return null;
- }
- Constructor<?> defaultConstructor = null;
- for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
- if (constructor.getParameterTypes().length == 0) {
- defaultConstructor = constructor;
- break;
- }
- }
-
- if (defaultConstructor == null) {
- if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
- for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
- if (constructor.getParameterTypes().length == 1 && constructor.getParameterTypes()[0].equals(clazz.getDeclaringClass())) {
- defaultConstructor = constructor;
- break;
- }
- }
- }
- }
-
- return defaultConstructor;
- }
- public static Constructor<?> getCreatorConstructor(Class<?> clazz) {
- Constructor<?> creatorConstructor = null;
- for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
- JSONCreator annotation = constructor.getAnnotation(JSONCreator.class);
- if (annotation != null) {
- if (creatorConstructor != null) {
- throw new JSONException("multi-json creator");
- }
- creatorConstructor = constructor;
- break;
- }
- }
- return creatorConstructor;
- }
- public static Method getFactoryMethod(Class<?> clazz) {
- Method factoryMethod = null;
- for (Method method : clazz.getDeclaredMethods()) {
- if (!Modifier.isStatic(method.getModifiers())) {
- continue;
- }
- if (!clazz.isAssignableFrom(method.getReturnType())) {
- continue;
- }
- JSONCreator annotation = method.getAnnotation(JSONCreator.class);
- if (annotation != null) {
- if (factoryMethod != null) {
- throw new JSONException("multi-json creator");
- }
- factoryMethod = method;
- break;
- }
- }
- return factoryMethod;
- }
- }