use of com.alibaba.fastjson.annotation.JSONField 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);
}
use of com.alibaba.fastjson.annotation.JSONField in project fastjson by alibaba.
the class FieldSerializer method writeValue.
public void writeValue(JSONSerializer serializer, Object propertyValue) throws Exception {
if (runtimeInfo == null) {
Class<?> runtimeFieldClass;
if (propertyValue == null) {
runtimeFieldClass = this.fieldInfo.fieldClass;
} else {
runtimeFieldClass = propertyValue.getClass();
}
ObjectSerializer fieldSerializer = null;
JSONField fieldAnnotation = fieldInfo.getAnnotation();
if (fieldAnnotation != null && fieldAnnotation.serializeUsing() != Void.class) {
fieldSerializer = (ObjectSerializer) fieldAnnotation.serializeUsing().newInstance();
serializeUsing = true;
} else {
if (format != null) {
if (runtimeFieldClass == double.class || runtimeFieldClass == Double.class) {
fieldSerializer = new DoubleSerializer(format);
} else if (runtimeFieldClass == float.class || runtimeFieldClass == Float.class) {
fieldSerializer = new FloatCodec(format);
}
}
if (fieldSerializer == null) {
fieldSerializer = serializer.getObjectWriter(runtimeFieldClass);
}
}
runtimeInfo = new RuntimeSerializerInfo(fieldSerializer, runtimeFieldClass);
}
final RuntimeSerializerInfo runtimeInfo = this.runtimeInfo;
final int fieldFeatures = fieldInfo.serialzeFeatures;
if (propertyValue == null) {
Class<?> runtimeFieldClass = runtimeInfo.runtimeFieldClass;
SerializeWriter out = serializer.out;
if (Number.class.isAssignableFrom(runtimeFieldClass)) {
out.writeNull(features, SerializerFeature.WriteNullNumberAsZero.mask);
return;
} else if (String.class == runtimeFieldClass) {
out.writeNull(features, SerializerFeature.WriteNullStringAsEmpty.mask);
return;
} else if (Boolean.class == runtimeFieldClass) {
out.writeNull(features, SerializerFeature.WriteNullBooleanAsFalse.mask);
return;
} else if (Collection.class.isAssignableFrom(runtimeFieldClass)) {
out.writeNull(features, SerializerFeature.WriteNullListAsEmpty.mask);
return;
}
ObjectSerializer fieldSerializer = runtimeInfo.fieldSerializer;
if ((out.isEnabled(SerializerFeature.WRITE_MAP_NULL_FEATURES)) && fieldSerializer instanceof JavaBeanSerializer) {
out.writeNull();
return;
}
fieldSerializer.write(serializer, null, fieldInfo.name, fieldInfo.fieldType, fieldFeatures);
return;
}
if (fieldInfo.isEnum) {
if (writeEnumUsingName) {
serializer.out.writeString(((Enum<?>) propertyValue).name());
return;
}
if (writeEnumUsingToString) {
serializer.out.writeString(((Enum<?>) propertyValue).toString());
return;
}
}
Class<?> valueClass = propertyValue.getClass();
ObjectSerializer valueSerializer;
if (valueClass == runtimeInfo.runtimeFieldClass || serializeUsing) {
valueSerializer = runtimeInfo.fieldSerializer;
} else {
valueSerializer = serializer.getObjectWriter(valueClass);
}
if (format != null && !(valueSerializer instanceof DoubleSerializer || valueSerializer instanceof FloatCodec)) {
if (valueSerializer instanceof ContextObjectSerializer) {
((ContextObjectSerializer) valueSerializer).write(serializer, propertyValue, this.fieldContext);
} else {
serializer.writeWithFormat(propertyValue, format);
}
} else {
valueSerializer.write(serializer, propertyValue, fieldInfo.name, fieldInfo.fieldType, fieldFeatures);
}
}
use of com.alibaba.fastjson.annotation.JSONField in project fastjson by alibaba.
the class ASMSerializerFactory method _if_write_null.
private void _if_write_null(MethodVisitor mw, FieldInfo fieldInfo, Context context) {
Class<?> propertyClass = fieldInfo.fieldClass;
Label _if = new Label();
Label _else = new Label();
Label _write_null = new Label();
Label _end_if = new Label();
mw.visitLabel(_if);
JSONField annotation = fieldInfo.getAnnotation();
int features = 0;
if (annotation != null) {
features = SerializerFeature.of(annotation.serialzeFeatures());
;
}
if ((features & SerializerFeature.WRITE_MAP_NULL_FEATURES) == 0) {
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(SerializerFeature.WRITE_MAP_NULL_FEATURES);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFEQ, _else);
}
mw.visitLabel(_write_null);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
_writeFieldName(mw, context);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(features);
if (propertyClass == String.class || propertyClass == Character.class) {
mw.visitLdcInsn(SerializerFeature.WriteNullStringAsEmpty.mask);
} else if (Number.class.isAssignableFrom(propertyClass)) {
mw.visitLdcInsn(SerializerFeature.WriteNullNumberAsZero.mask);
} else if (propertyClass == Boolean.class) {
mw.visitLdcInsn(SerializerFeature.WriteNullBooleanAsFalse.mask);
} else if (Collection.class.isAssignableFrom(propertyClass) || propertyClass.isArray()) {
mw.visitLdcInsn(SerializerFeature.WriteNullListAsEmpty.mask);
} else {
mw.visitLdcInsn(0);
}
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeNull", "(II)V");
// seperator = ',';
_seperator(mw, context);
mw.visitJumpInsn(GOTO, _end_if);
mw.visitLabel(_else);
mw.visitLabel(_end_if);
}
use of com.alibaba.fastjson.annotation.JSONField in project fastjson by alibaba.
the class TypeUtils method computeGetters.
public static //
List<FieldInfo> computeGetters(//
Class<?> clazz, //
JSONType jsonType, //
Map<String, String> aliasMap, //
Map<String, Field> fieldCacheMap, //
boolean sorted, //
PropertyNamingStrategy propertyNamingStrategy) {
Map<String, FieldInfo> fieldInfoMap = new LinkedHashMap<String, FieldInfo>();
for (Method method : clazz.getMethods()) {
String methodName = method.getName();
int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
String label = null;
if (Modifier.isStatic(method.getModifiers())) {
continue;
}
if (method.getReturnType().equals(Void.TYPE)) {
continue;
}
if (method.getParameterTypes().length != 0) {
continue;
}
if (method.getReturnType() == ClassLoader.class) {
continue;
}
if (method.getName().equals("getMetaClass") && method.getReturnType().getName().equals("groovy.lang.MetaClass")) {
continue;
}
JSONField annotation = method.getAnnotation(JSONField.class);
if (annotation == null) {
annotation = getSuperMethodAnnotation(clazz, method);
}
if (annotation != null) {
if (!annotation.serialize()) {
continue;
}
ordinal = annotation.ordinal();
serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
parserFeatures = Feature.of(annotation.parseFeatures());
if (annotation.name().length() != 0) {
String propertyName = annotation.name();
if (aliasMap != null) {
propertyName = aliasMap.get(propertyName);
if (propertyName == null) {
continue;
}
}
FieldInfo fieldInfo = new FieldInfo(propertyName, method, null, clazz, null, ordinal, serialzeFeatures, parserFeatures, annotation, null, label);
fieldInfoMap.put(propertyName, fieldInfo);
continue;
}
if (annotation.label().length() != 0) {
label = annotation.label();
}
}
if (methodName.startsWith("get")) {
if (methodName.length() < 4) {
continue;
}
if (methodName.equals("getClass")) {
continue;
}
if (methodName.equals("getDeclaringClass") && clazz.isEnum()) {
continue;
}
char c3 = methodName.charAt(3);
String propertyName;
if (//
Character.isUpperCase(c3) || // for unicode method name
c3 > 512) {
if (compatibleWithJavaBean) {
propertyName = decapitalize(methodName.substring(3));
} else {
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
}
propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 3);
} 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 = decapitalize(methodName.substring(3));
} else {
continue;
}
boolean ignore = isJSONTypeIgnore(clazz, propertyName);
if (ignore) {
continue;
}
//假如bean的field很多的情况一下,轮询时将大大降低效率
Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
if (field == null && propertyName.length() > 1) {
char ch = propertyName.charAt(1);
if (ch >= 'A' && ch <= 'Z') {
String javaBeanCompatiblePropertyName = decapitalize(methodName.substring(3));
field = ParserConfig.getFieldFromCache(javaBeanCompatiblePropertyName, fieldCacheMap);
}
}
JSONField fieldAnnotation = null;
if (field != null) {
fieldAnnotation = field.getAnnotation(JSONField.class);
if (fieldAnnotation != null) {
if (!fieldAnnotation.serialize()) {
continue;
}
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
if (fieldAnnotation.name().length() != 0) {
propertyName = fieldAnnotation.name();
if (aliasMap != null) {
propertyName = aliasMap.get(propertyName);
if (propertyName == null) {
continue;
}
}
}
if (fieldAnnotation.label().length() != 0) {
label = fieldAnnotation.label();
}
}
}
if (aliasMap != null) {
propertyName = aliasMap.get(propertyName);
if (propertyName == null) {
continue;
}
}
if (propertyNamingStrategy != null) {
propertyName = propertyNamingStrategy.translate(propertyName);
}
FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, label);
fieldInfoMap.put(propertyName, fieldInfo);
}
if (methodName.startsWith("is")) {
if (methodName.length() < 3) {
continue;
}
if (method.getReturnType() != Boolean.TYPE && method.getReturnType() != Boolean.class) {
continue;
}
char c2 = methodName.charAt(2);
String propertyName;
if (Character.isUpperCase(c2)) {
if (compatibleWithJavaBean) {
propertyName = decapitalize(methodName.substring(2));
} else {
propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3);
}
propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 2);
} else if (c2 == '_') {
propertyName = methodName.substring(3);
} else if (c2 == 'f') {
propertyName = methodName.substring(2);
} else {
continue;
}
Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
if (field == null) {
field = ParserConfig.getFieldFromCache(methodName, fieldCacheMap);
}
JSONField fieldAnnotation = null;
if (field != null) {
fieldAnnotation = field.getAnnotation(JSONField.class);
if (fieldAnnotation != null) {
if (!fieldAnnotation.serialize()) {
continue;
}
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
if (fieldAnnotation.name().length() != 0) {
propertyName = fieldAnnotation.name();
if (aliasMap != null) {
propertyName = aliasMap.get(propertyName);
if (propertyName == null) {
continue;
}
}
}
if (fieldAnnotation.label().length() != 0) {
label = fieldAnnotation.label();
}
}
}
if (aliasMap != null) {
propertyName = aliasMap.get(propertyName);
if (propertyName == null) {
continue;
}
}
if (propertyNamingStrategy != null) {
propertyName = propertyNamingStrategy.translate(propertyName);
}
//优先选择get
if (fieldInfoMap.containsKey(propertyName)) {
continue;
}
FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, label);
fieldInfoMap.put(propertyName, fieldInfo);
}
}
for (Field field : clazz.getFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
String propertyName = field.getName();
String label = null;
if (fieldAnnotation != null) {
if (!fieldAnnotation.serialize()) {
continue;
}
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
if (fieldAnnotation.name().length() != 0) {
propertyName = fieldAnnotation.name();
}
if (fieldAnnotation.label().length() != 0) {
label = fieldAnnotation.label();
}
}
if (aliasMap != null) {
propertyName = aliasMap.get(propertyName);
if (propertyName == null) {
continue;
}
}
if (propertyNamingStrategy != null) {
propertyName = propertyNamingStrategy.translate(propertyName);
}
if (!fieldInfoMap.containsKey(propertyName)) {
FieldInfo fieldInfo = new FieldInfo(propertyName, null, field, clazz, null, ordinal, serialzeFeatures, parserFeatures, null, fieldAnnotation, label);
fieldInfoMap.put(propertyName, fieldInfo);
}
}
List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
boolean containsAll = false;
String[] orders = null;
JSONType annotation = clazz.getAnnotation(JSONType.class);
if (annotation != null) {
orders = annotation.orders();
if (orders != null && orders.length == fieldInfoMap.size()) {
containsAll = true;
for (String item : orders) {
if (!fieldInfoMap.containsKey(item)) {
containsAll = false;
break;
}
}
} else {
containsAll = false;
}
}
if (containsAll) {
for (String item : orders) {
FieldInfo fieldInfo = fieldInfoMap.get(item);
fieldInfoList.add(fieldInfo);
}
} else {
for (FieldInfo fieldInfo : fieldInfoMap.values()) {
fieldInfoList.add(fieldInfo);
}
if (sorted) {
Collections.sort(fieldInfoList);
}
}
return fieldInfoList;
}
use of com.alibaba.fastjson.annotation.JSONField in project fastjson by alibaba.
the class ParserConfigBug569 method createFieldDeserializer.
public //
FieldDeserializer createFieldDeserializer(//
ParserConfig mapping, //
JavaBeanInfo beanInfo, FieldInfo fieldInfo) {
Class<?> clazz = beanInfo.clazz;
Class<?> fieldClass = fieldInfo.fieldClass;
Class<?> deserializeUsing = null;
JSONField annotation = fieldInfo.getAnnotation();
if (annotation != null) {
deserializeUsing = annotation.deserializeUsing();
if (deserializeUsing == Void.class) {
deserializeUsing = null;
}
}
if (deserializeUsing == null && (fieldClass == List.class || fieldClass == ArrayList.class)) {
return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
}
return new DefaultFieldDeserializerBug569(mapping, clazz, fieldInfo);
}
Aggregations