All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.alibaba.fastjson.util.DeserializeBeanInfo Maven / Gradle / Ivy
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.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class DeserializeBeanInfo {
private final Class> clazz;
private Constructor> defaultConstructor;
private Constructor> creatorConstructor;
private Method factoryMethod;
private final List fieldList = new ArrayList();
private final List sortedFieldList = new ArrayList();
private int parserFeatures = 0;
public DeserializeBeanInfo(Class> clazz){
super();
this.clazz = clazz;
this.parserFeatures = TypeUtils.getParserFeatures(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 List getFieldList() {
return fieldList;
}
public List getSortedFieldList() {
return sortedFieldList;
}
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())) {
if (item.isGetOnly() && !field.isGetOnly()) {
continue;
}
if (item.getFieldClass().isAssignableFrom(field.getFieldClass())) {
fieldList.remove(item);
break;
}
return false;
}
}
fieldList.add(field);
sortedFieldList.add(field);
Collections.sort(sortedFieldList);
return true;
}
public static DeserializeBeanInfo computeSetters(Class> clazz, Type type) {
DeserializeBeanInfo beanInfo = new DeserializeBeanInfo(clazz);
Constructor> defaultConstructor = getDefaultConstructor(clazz);
if (defaultConstructor != null) {
TypeUtils.setAccessible(defaultConstructor);
beanInfo.setDefaultConstructor(defaultConstructor);
} else if (defaultConstructor == null && !(clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()))) {
Constructor> creatorConstructor = getCreatorConstructor(clazz);
if (creatorConstructor != null) {
TypeUtils.setAccessible(creatorConstructor);
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 = TypeUtils.getField(clazz, fieldAnnotation.name());
final int ordinal = fieldAnnotation.ordinal();
final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field,
ordinal, serialzeFeatures);
beanInfo.add(fieldInfo);
}
return beanInfo;
}
Method factoryMethod = getFactoryMethod(clazz);
if (factoryMethod != null) {
TypeUtils.setAccessible(factoryMethod);
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 = TypeUtils.getField(clazz, fieldAnnotation.name());
final int ordinal = fieldAnnotation.ordinal();
final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name() //
, clazz //
, fieldClass //
, fieldType //
, field //
, ordinal //
, serialzeFeatures);
beanInfo.add(fieldInfo);
}
return beanInfo;
}
throw new JSONException("default constructor not found. " + clazz);
}
for (Method method : clazz.getMethods()) {
int ordinal = 0, serialzeFeatures = 0;
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) {
annotation = TypeUtils.getSupperMethodAnnotation(clazz, method);
}
if (annotation != null) {
if (!annotation.deserialize()) {
continue;
}
ordinal = annotation.ordinal();
serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
if (annotation.name().length() != 0) {
String propertyName = annotation.name();
beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures));
TypeUtils.setAccessible(method);
continue;
}
}
if (!methodName.startsWith("set")) {
continue;
}
char c3 = methodName.charAt(3);
String propertyName;
if (Character.isUpperCase(c3)) {
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);
if (field == null && method.getParameterTypes()[0] == boolean.class) {
String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
field = TypeUtils.getField(clazz, isFieldName);
}
if (field != null) {
JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
if (fieldAnnotation != null) {
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
if (fieldAnnotation.name().length() != 0) {
propertyName = fieldAnnotation.name();
beanInfo.add(new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures));
continue;
}
}
}
beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures));
TypeUtils.setAccessible(method);
}
for (Field field : clazz.getFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
boolean contains = false;
for (FieldInfo item : beanInfo.getFieldList()) {
if (item.getName().equals(field.getName())) {
contains = true;
continue;
}
}
if (contains) {
continue;
}
int ordinal = 0, serialzeFeatures = 0;
String propertyName = field.getName();
JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
if (fieldAnnotation != null) {
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
if (fieldAnnotation.name().length() != 0) {
propertyName = fieldAnnotation.name();
}
}
beanInfo.add(new FieldInfo(propertyName, null, field, clazz, type, ordinal, serialzeFeatures));
}
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()) //
|| 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.name().length() > 0) {
propertyName = annotation.name();
} else {
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));
TypeUtils.setAccessible(method);
}
}
}
return beanInfo;
}
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;
}
public int getParserFeatures() {
return parserFeatures;
}
}