use of com.alibaba.fastjson.annotation.JSONType in project fastjson by alibaba.
the class ParserConfig method createJavaBeanDeserializer.
public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
boolean asmEnable = this.asmEnable & !this.fieldBased;
if (asmEnable) {
JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
if (jsonType != null) {
Class<?> deserializerClass = jsonType.deserializer();
if (deserializerClass != Void.class) {
try {
Object deseralizer = deserializerClass.newInstance();
if (deseralizer instanceof ObjectDeserializer) {
return (ObjectDeserializer) deseralizer;
}
} catch (Throwable e) {
// skip
}
}
asmEnable = jsonType.asm() && jsonType.parseFeatures().length == 0;
}
if (asmEnable) {
Class<?> superClass = JavaBeanInfo.getBuilderClass(clazz, jsonType);
if (superClass == null) {
superClass = clazz;
}
for (; ; ) {
if (!Modifier.isPublic(superClass.getModifiers())) {
asmEnable = false;
break;
}
superClass = superClass.getSuperclass();
if (superClass == Object.class || superClass == null) {
break;
}
}
}
}
if (clazz.getTypeParameters().length != 0) {
asmEnable = false;
}
if (asmEnable && asmFactory != null && asmFactory.classLoader.isExternalClass(clazz)) {
asmEnable = false;
}
if (asmEnable) {
asmEnable = ASMUtils.checkName(clazz.getSimpleName());
}
if (asmEnable) {
if (clazz.isInterface()) {
asmEnable = false;
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy, false, TypeUtils.compatibleWithJavaBean, jacksonCompatible);
if (asmEnable && beanInfo.fields.length > 200) {
asmEnable = false;
}
Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
if (asmEnable && defaultConstructor == null && !clazz.isInterface()) {
asmEnable = false;
}
for (FieldInfo fieldInfo : beanInfo.fields) {
if (fieldInfo.getOnly) {
asmEnable = false;
break;
}
Class<?> fieldClass = fieldInfo.fieldClass;
if (!Modifier.isPublic(fieldClass.getModifiers())) {
asmEnable = false;
break;
}
if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) {
asmEnable = false;
break;
}
if (//
fieldInfo.getMember() != null && !ASMUtils.checkName(fieldInfo.getMember().getName())) {
asmEnable = false;
break;
}
JSONField annotation = fieldInfo.getAnnotation();
if (//
annotation != null && (//
(!ASMUtils.checkName(annotation.name())) || //
annotation.format().length() != 0 || //
annotation.deserializeUsing() != Void.class || //
annotation.parseFeatures().length != 0 || annotation.unwrapped()) || (fieldInfo.method != null && fieldInfo.method.getParameterTypes().length > 1)) {
asmEnable = false;
break;
}
if (fieldClass.isEnum()) {
// EnumDeserializer
ObjectDeserializer fieldDeser = this.getDeserializer(fieldClass);
if (!(fieldDeser instanceof EnumDeserializer)) {
asmEnable = false;
break;
}
}
}
}
if (asmEnable) {
if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
asmEnable = false;
}
}
if (asmEnable) {
if (TypeUtils.isXmlField(clazz)) {
asmEnable = false;
}
}
if (!asmEnable) {
return new JavaBeanDeserializer(this, clazz, type);
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy);
try {
return asmFactory.createJavaBeanDeserializer(this, beanInfo);
// } catch (VerifyError e) {
// e.printStackTrace();
// return new JavaBeanDeserializer(this, clazz, type);
} catch (NoSuchMethodException ex) {
return new JavaBeanDeserializer(this, clazz, type);
} catch (JSONException asmError) {
return new JavaBeanDeserializer(this, beanInfo);
} catch (Exception e) {
throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
}
}
use of com.alibaba.fastjson.annotation.JSONType 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());
}
JSONType jsonType = context.beanInfo.jsonType;
if (jsonType != null) {
features |= SerializerFeature.of(jsonType.serialzeFeatures());
}
int writeNullFeatures;
if (propertyClass == String.class) {
writeNullFeatures = SerializerFeature.WriteMapNullValue.getMask() | SerializerFeature.WriteNullStringAsEmpty.getMask();
} else if (Number.class.isAssignableFrom(propertyClass)) {
writeNullFeatures = SerializerFeature.WriteMapNullValue.getMask() | SerializerFeature.WriteNullNumberAsZero.getMask();
} else if (Collection.class.isAssignableFrom(propertyClass)) {
writeNullFeatures = SerializerFeature.WriteMapNullValue.getMask() | SerializerFeature.WriteNullListAsEmpty.getMask();
} else if (Boolean.class == propertyClass) {
writeNullFeatures = SerializerFeature.WriteMapNullValue.getMask() | SerializerFeature.WriteNullBooleanAsFalse.getMask();
} else {
writeNullFeatures = SerializerFeature.WRITE_MAP_NULL_FEATURES;
}
if ((features & writeNullFeatures) == 0) {
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(writeNullFeatures);
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.JSONType in project uavstack by uavorg.
the class ASMSerializerFactory method createJavaBeanSerializer.
public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, String> aliasMap) throws Exception {
if (clazz.isPrimitive()) {
throw new JSONException("unsupportd class " + clazz.getName());
}
List<FieldInfo> getters = TypeUtils.computeGetters(clazz, aliasMap, false);
for (FieldInfo getter : getters) {
if (!ASMUtils.checkName(getter.getMember().getName())) {
return null;
}
}
String className = getGenClassName(clazz);
int beanSerializeFeatures = TypeUtils.getSerializeFeatures(clazz);
ClassWriter cw = new ClassWriter();
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, "com/alibaba/fastjson/serializer/ASMJavaBeanSerializer", new String[] { "com/alibaba/fastjson/serializer/ObjectSerializer" });
for (FieldInfo fieldInfo : getters) {
{
FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldPrefix", "Ljava/lang/reflect/Type;");
fw.visitEnd();
}
FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldType", "Ljava/lang/reflect/Type;");
fw.visitEnd();
}
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(clazz)));
mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/serializer/ASMJavaBeanSerializer", "<init>", "(Ljava/lang/Class;)V");
for (FieldInfo fieldInfo : getters) {
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getDeclaringClass())));
if (fieldInfo.getMethod() != null) {
mw.visitLdcInsn(fieldInfo.getMethod().getName());
mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/util/ASMUtils", "getMethodType", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
} else {
mw.visitLdcInsn(fieldInfo.getField().getName());
mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/util/ASMUtils", "getFieldType", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
}
mw.visitFieldInsn(PUTFIELD, className, fieldInfo.getName() + "_asm_fieldType", "Ljava/lang/reflect/Type;");
}
mw.visitInsn(RETURN);
mw.visitMaxs(4, 4);
mw.visitEnd();
{
Context context = new Context(className, beanSerializeFeatures);
mw = cw.visitMethod(ACC_PUBLIC, "write", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", null, new String[] { "java/io/IOException" });
// serializer
mw.visitVarInsn(ALOAD, context.serializer());
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", "()Lcom/alibaba/fastjson/serializer/SerializeWriter;");
mw.visitVarInsn(ASTORE, context.var("out"));
JSONType jsonType = clazz.getAnnotation(JSONType.class);
if (jsonType == null || jsonType.alphabetic()) {
Label _else = new Label();
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "SortField", "Lcom/alibaba/fastjson/serializer/SerializerFeature;");
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", "(Lcom/alibaba/fastjson/serializer/SerializerFeature;)Z");
mw.visitJumpInsn(IFEQ, _else);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, className, "write1", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_else);
}
// obj
mw.visitVarInsn(ALOAD, context.obj());
// serializer
mw.visitTypeInsn(CHECKCAST, getType(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteMethod(clazz, mw, getters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(6, context.getVariantCount() + 1);
mw.visitEnd();
}
List<FieldInfo> sortedGetters = TypeUtils.computeGetters(clazz, aliasMap, true);
{
// sortField support
Context context = new Context(className, beanSerializeFeatures);
mw = cw.visitMethod(ACC_PUBLIC, "write1", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", null, new String[] { "java/io/IOException" });
// serializer
mw.visitVarInsn(ALOAD, context.serializer());
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", "()Lcom/alibaba/fastjson/serializer/SerializeWriter;");
mw.visitVarInsn(ASTORE, context.var("out"));
// obj
mw.visitVarInsn(ALOAD, context.obj());
// serializer
mw.visitTypeInsn(CHECKCAST, getType(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteMethod(clazz, mw, sortedGetters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(6, context.getVariantCount() + 1);
mw.visitEnd();
}
// writeAsArray
{
Context context = new Context(className, beanSerializeFeatures);
mw = cw.visitMethod(ACC_PUBLIC, "writeAsArray", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V", null, new String[] { "java/io/IOException" });
// serializer
mw.visitVarInsn(ALOAD, context.serializer());
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", "()Lcom/alibaba/fastjson/serializer/SerializeWriter;");
mw.visitVarInsn(ASTORE, context.var("out"));
// obj
mw.visitVarInsn(ALOAD, context.obj());
// serializer
mw.visitTypeInsn(CHECKCAST, getType(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteAsArray(clazz, mw, sortedGetters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(6, context.getVariantCount() + 1);
mw.visitEnd();
}
byte[] code = cw.toByteArray();
if (JSON.DUMP_CLASS != null) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(JSON.DUMP_CLASS + File.separator + className + ".class");
fos.write(code);
} catch (Exception ex) {
// System.err.println("FASTJSON dump class:"+className+"失败:"+ex.getMessage());
} finally {
if (fos != null) {
fos.close();
}
}
}
Class<?> exampleClass = classLoader.defineClassPublic(className, code, 0, code.length);
Object instance = exampleClass.newInstance();
return (ObjectSerializer) instance;
}
use of com.alibaba.fastjson.annotation.JSONType in project fastjson by alibaba.
the class SerializeConfig method getObjectWriter.
public ObjectSerializer getObjectWriter(Class<?> clazz, boolean create) {
ObjectSerializer writer = get(clazz);
if (writer != null) {
return writer;
}
try {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
if (!(o instanceof AutowiredObjectSerializer)) {
continue;
}
AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
for (Type forType : autowired.getAutowiredFor()) {
put(forType, autowired);
}
}
} catch (ClassCastException ex) {
// skip
}
writer = get(clazz);
if (writer == null) {
final ClassLoader classLoader = JSON.class.getClassLoader();
if (classLoader != Thread.currentThread().getContextClassLoader()) {
try {
for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
if (!(o instanceof AutowiredObjectSerializer)) {
continue;
}
AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
for (Type forType : autowired.getAutowiredFor()) {
put(forType, autowired);
}
}
} catch (ClassCastException ex) {
// skip
}
writer = get(clazz);
}
}
for (Module module : modules) {
writer = module.createSerializer(this, clazz);
if (writer != null) {
put(clazz, writer);
return writer;
}
}
if (writer == null) {
String className = clazz.getName();
Class<?> superClass;
if (Map.class.isAssignableFrom(clazz)) {
put(clazz, writer = MapSerializer.instance);
} else if (List.class.isAssignableFrom(clazz)) {
put(clazz, writer = ListSerializer.instance);
} else if (Collection.class.isAssignableFrom(clazz)) {
put(clazz, writer = CollectionCodec.instance);
} else if (Date.class.isAssignableFrom(clazz)) {
put(clazz, writer = DateCodec.instance);
} else if (JSONAware.class.isAssignableFrom(clazz)) {
put(clazz, writer = JSONAwareSerializer.instance);
} else if (JSONSerializable.class.isAssignableFrom(clazz)) {
put(clazz, writer = JSONSerializableSerializer.instance);
} else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
put(clazz, writer = MiscCodec.instance);
} else if (clazz.isEnum()) {
Class mixedInType = (Class) JSON.getMixInAnnotations(clazz);
JSONType jsonType;
if (mixedInType != null) {
jsonType = TypeUtils.getAnnotation(mixedInType, JSONType.class);
} else {
jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
}
if (jsonType != null && jsonType.serializeEnumAsJavaBean()) {
put(clazz, writer = createJavaBeanSerializer(clazz));
} else {
Member member = null;
if (mixedInType != null) {
Member mixedInMember = getEnumValueField(mixedInType);
if (mixedInMember != null) {
try {
if (mixedInMember instanceof Method) {
Method mixedInMethod = (Method) mixedInMember;
member = clazz.getMethod(mixedInMethod.getName(), mixedInMethod.getParameterTypes());
}
} catch (Exception e) {
// skip
}
}
} else {
member = getEnumValueField(clazz);
}
if (member != null) {
put(clazz, writer = new EnumSerializer(member));
} else {
put(clazz, writer = getEnumSerializer());
}
}
} else if ((superClass = clazz.getSuperclass()) != null && superClass.isEnum()) {
JSONType jsonType = TypeUtils.getAnnotation(superClass, JSONType.class);
if (jsonType != null && jsonType.serializeEnumAsJavaBean()) {
put(clazz, writer = createJavaBeanSerializer(clazz));
} else {
put(clazz, writer = getEnumSerializer());
}
} else if (clazz.isArray()) {
Class<?> componentType = clazz.getComponentType();
ObjectSerializer compObjectSerializer = getObjectWriter(componentType);
put(clazz, writer = new ArraySerializer(componentType, compObjectSerializer));
} else if (Throwable.class.isAssignableFrom(clazz)) {
SerializeBeanInfo beanInfo = TypeUtils.buildBeanInfo(clazz, null, propertyNamingStrategy);
beanInfo.features |= SerializerFeature.WriteClassName.mask;
put(clazz, writer = new JavaBeanSerializer(beanInfo));
} else if (TimeZone.class.isAssignableFrom(clazz) || Map.Entry.class.isAssignableFrom(clazz)) {
put(clazz, writer = MiscCodec.instance);
} else if (Appendable.class.isAssignableFrom(clazz)) {
put(clazz, writer = AppendableSerializer.instance);
} else if (Charset.class.isAssignableFrom(clazz)) {
put(clazz, writer = ToStringSerializer.instance);
} else if (Enumeration.class.isAssignableFrom(clazz)) {
put(clazz, writer = EnumerationSerializer.instance);
} else if (//
Calendar.class.isAssignableFrom(clazz) || XMLGregorianCalendar.class.isAssignableFrom(clazz)) {
put(clazz, writer = CalendarCodec.instance);
} else if (TypeUtils.isClob(clazz)) {
put(clazz, writer = ClobSerializer.instance);
} else if (TypeUtils.isPath(clazz)) {
put(clazz, writer = ToStringSerializer.instance);
} else if (Iterator.class.isAssignableFrom(clazz)) {
put(clazz, writer = MiscCodec.instance);
} else if (org.w3c.dom.Node.class.isAssignableFrom(clazz)) {
put(clazz, writer = MiscCodec.instance);
} else {
if (//
className.startsWith("java.awt.") && //
AwtCodec.support(clazz)) {
// awt
if (!awtError) {
try {
String[] names = new String[] { "java.awt.Color", "java.awt.Font", "java.awt.Point", "java.awt.Rectangle" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = AwtCodec.instance);
return writer;
}
}
} catch (Throwable e) {
awtError = true;
// skip
}
}
}
// jdk8
if (//
(!jdk8Error) && (//
className.startsWith("java.time.") || //
className.startsWith("java.util.Optional") || className.equals("java.util.concurrent.atomic.LongAdder") || className.equals("java.util.concurrent.atomic.DoubleAdder"))) {
try {
{
String[] names = new String[] { "java.time.LocalDateTime", "java.time.LocalDate", "java.time.LocalTime", "java.time.ZonedDateTime", "java.time.OffsetDateTime", "java.time.OffsetTime", "java.time.ZoneOffset", "java.time.ZoneRegion", "java.time.Period", "java.time.Duration", "java.time.Instant" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = Jdk8DateCodec.instance);
return writer;
}
}
}
{
String[] names = new String[] { "java.util.Optional", "java.util.OptionalDouble", "java.util.OptionalInt", "java.util.OptionalLong" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = OptionalCodec.instance);
return writer;
}
}
}
{
String[] names = new String[] { "java.util.concurrent.atomic.LongAdder", "java.util.concurrent.atomic.DoubleAdder" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = AdderSerializer.instance);
return writer;
}
}
}
} catch (Throwable e) {
// skip
jdk8Error = true;
}
}
if (//
(!oracleJdbcError) && className.startsWith("oracle.sql.")) {
try {
String[] names = new String[] { "oracle.sql.DATE", "oracle.sql.TIMESTAMP" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = DateCodec.instance);
return writer;
}
}
} catch (Throwable e) {
// skip
oracleJdbcError = true;
}
}
if (//
(!springfoxError) && className.equals("springfox.documentation.spring.web.json.Json")) {
try {
put(//
Class.forName("springfox.documentation.spring.web.json.Json"), writer = SwaggerJsonSerializer.instance);
return writer;
} catch (ClassNotFoundException e) {
// skip
springfoxError = true;
}
}
if (//
(!guavaError) && className.startsWith("com.google.common.collect.")) {
try {
String[] names = new String[] { "com.google.common.collect.HashMultimap", "com.google.common.collect.LinkedListMultimap", "com.google.common.collect.LinkedHashMultimap", "com.google.common.collect.ArrayListMultimap", "com.google.common.collect.TreeMultimap" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = GuavaCodec.instance);
return writer;
}
}
} catch (ClassNotFoundException e) {
// skip
guavaError = true;
}
}
if (className.equals("net.sf.json.JSONNull")) {
put(clazz, writer = MiscCodec.instance);
return writer;
}
if (className.equals("org.json.JSONObject")) {
put(clazz, writer = JSONObjectCodec.instance);
return writer;
}
if ((!jodaError) && className.startsWith("org.joda.")) {
try {
String[] names = new String[] { "org.joda.time.LocalDate", "org.joda.time.LocalDateTime", "org.joda.time.LocalTime", "org.joda.time.Instant", "org.joda.time.DateTime", "org.joda.time.Period", "org.joda.time.Duration", "org.joda.time.DateTimeZone", "org.joda.time.UTCDateTimeZone", "org.joda.time.tz.CachedDateTimeZone", "org.joda.time.tz.FixedDateTimeZone" };
for (String name : names) {
if (name.equals(className)) {
put(Class.forName(name), writer = JodaCodec.instance);
return writer;
}
}
} catch (ClassNotFoundException e) {
// skip
jodaError = true;
}
}
if ("java.nio.HeapByteBuffer".equals(className)) {
put(clazz, writer = ByteBufferCodec.instance);
return writer;
}
if ("org.javamoney.moneta.Money".equals(className)) {
put(clazz, writer = MonetaCodec.instance);
return writer;
}
if ("com.google.protobuf.Descriptors$FieldDescriptor".equals(className)) {
put(clazz, writer = ToStringSerializer.instance);
return writer;
}
Class[] interfaces = clazz.getInterfaces();
if (interfaces.length == 1 && interfaces[0].isAnnotation()) {
put(clazz, AnnotationSerializer.instance);
return AnnotationSerializer.instance;
}
if (TypeUtils.isProxy(clazz)) {
Class<?> superClazz = clazz.getSuperclass();
ObjectSerializer superWriter = getObjectWriter(superClazz);
put(clazz, superWriter);
return superWriter;
}
if (Proxy.isProxyClass(clazz)) {
Class handlerClass = null;
if (interfaces.length == 2) {
handlerClass = interfaces[1];
} else {
for (Class proxiedInterface : interfaces) {
if (proxiedInterface.getName().startsWith("org.springframework.aop.")) {
continue;
}
if (handlerClass != null) {
// multi-matched
handlerClass = null;
break;
}
handlerClass = proxiedInterface;
}
}
if (handlerClass != null) {
ObjectSerializer superWriter = getObjectWriter(handlerClass);
put(clazz, superWriter);
return superWriter;
}
}
if (create) {
writer = createJavaBeanSerializer(clazz);
put(clazz, writer);
}
}
if (writer == null) {
writer = get(clazz);
}
}
return writer;
}
use of com.alibaba.fastjson.annotation.JSONType in project fastjson by alibaba.
the class ASMSerializerFactory method createJavaBeanSerializer.
public JavaBeanSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) throws Exception {
Class<?> clazz = beanInfo.beanType;
if (clazz.isPrimitive()) {
throw new JSONException("unsupportd class " + clazz.getName());
}
JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
FieldInfo[] unsortedGetters = beanInfo.fields;
for (FieldInfo fieldInfo : unsortedGetters) {
if (//
fieldInfo.field == null && //
fieldInfo.method != null && fieldInfo.method.getDeclaringClass().isInterface()) {
return new JavaBeanSerializer(beanInfo);
}
}
FieldInfo[] getters = beanInfo.sortedFields;
boolean nativeSorted = beanInfo.sortedFields == beanInfo.fields;
if (getters.length > 256) {
return new JavaBeanSerializer(beanInfo);
}
for (FieldInfo getter : getters) {
if (!ASMUtils.checkName(getter.getMember().getName())) {
return new JavaBeanSerializer(beanInfo);
}
}
String className = "ASMSerializer_" + seed.incrementAndGet() + "_" + clazz.getSimpleName();
String classNameType;
String classNameFull;
Package pkg = ASMSerializerFactory.class.getPackage();
if (pkg != null) {
String packageName = pkg.getName();
classNameType = packageName.replace('.', '/') + "/" + className;
classNameFull = packageName + "." + className;
} else {
classNameType = className;
classNameFull = className;
}
ClassWriter cw = new ClassWriter();
//
cw.visit(//
V1_5, //
ACC_PUBLIC + ACC_SUPER, //
classNameType, //
JavaBeanSerializer, //
new String[] { ObjectSerializer });
for (FieldInfo fieldInfo : getters) {
if (//
fieldInfo.fieldClass.isPrimitive() || // || fieldInfo.fieldClass.isEnum() //
fieldInfo.fieldClass == String.class) {
continue;
}
//
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_fieldType", "Ljava/lang/reflect/Type;").visitEnd();
if (List.class.isAssignableFrom(fieldInfo.fieldClass)) {
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_list_item_ser_", //
ObjectSerializer_desc).visitEnd();
}
//
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_ser_", ObjectSerializer_desc).visitEnd();
}
MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "<init>", "(" + desc(SerializeBeanInfo.class) + ")V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, "<init>", "(" + desc(SerializeBeanInfo.class) + ")V");
// init _asm_fieldType
for (int i = 0; i < getters.length; ++i) {
FieldInfo fieldInfo = getters[i];
if (//
fieldInfo.fieldClass.isPrimitive() || // || fieldInfo.fieldClass.isEnum() //
fieldInfo.fieldClass == String.class) {
continue;
}
mw.visitVarInsn(ALOAD, 0);
if (fieldInfo.method != null) {
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldInfo.declaringClass)));
mw.visitLdcInsn(fieldInfo.method.getName());
mw.visitMethodInsn(INVOKESTATIC, type(ASMUtils.class), "getMethodType", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
} else {
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(i);
mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, "getFieldType", "(I)Ljava/lang/reflect/Type;");
}
mw.visitFieldInsn(PUTFIELD, classNameType, fieldInfo.name + "_asm_fieldType", "Ljava/lang/reflect/Type;");
}
mw.visitInsn(RETURN);
mw.visitMaxs(4, 4);
mw.visitEnd();
boolean DisableCircularReferenceDetect = false;
if (jsonType != null) {
for (SerializerFeature featrues : jsonType.serialzeFeatures()) {
if (featrues == SerializerFeature.DisableCircularReferenceDetect) {
DisableCircularReferenceDetect = true;
break;
}
}
}
// 2 writeNonContext
for (int i = 0; i < 3; ++i) {
String methodName;
boolean nonContext = DisableCircularReferenceDetect;
boolean writeDirect = false;
if (i == 0) {
methodName = "write";
writeDirect = true;
} else if (i == 1) {
methodName = "writeNormal";
} else {
writeDirect = true;
nonContext = true;
methodName = "writeDirectNonContext";
}
Context context = new Context(getters, beanInfo, classNameType, writeDirect, nonContext);
mw = new //
MethodWriter(//
cw, //
ACC_PUBLIC, //
methodName, "(L" + JSONSerializer + //
";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", //
null, //
new String[] { "java/io/IOException" });
{
Label endIf_ = new Label();
mw.visitVarInsn(ALOAD, Context.obj);
// serializer.writeNull();
mw.visitJumpInsn(IFNONNULL, endIf_);
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeNull", "()V");
mw.visitInsn(RETURN);
mw.visitLabel(endIf_);
}
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));
if (//
(!nativeSorted) && !context.writeDirect) {
if (jsonType == null || jsonType.alphabetic()) {
Label _else = new Label();
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isSortField", "()Z");
mw.visitJumpInsn(IFNE, _else);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, classNameType, "writeUnsorted", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_else);
}
}
// isWriteDoubleQuoteDirect
if (context.writeDirect && !nonContext) {
Label _direct = new Label();
Label _directElse = new Label();
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitMethodInsn(INVOKEVIRTUAL, JavaBeanSerializer, "writeDirect", "(L" + JSONSerializer + ";)Z");
mw.visitJumpInsn(IFNE, _directElse);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, classNameType, "writeNormal", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_directElse);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(SerializerFeature.DisableCircularReferenceDetect.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFEQ, _direct);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, classNameType, "writeDirectNonContext", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_direct);
}
// obj
mw.visitVarInsn(ALOAD, Context.obj);
// serializer
mw.visitTypeInsn(CHECKCAST, type(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteMethod(clazz, mw, getters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(7, context.variantIndex + 2);
mw.visitEnd();
}
if (!nativeSorted) {
// sortField support
Context context = new Context(getters, beanInfo, classNameType, false, DisableCircularReferenceDetect);
mw = new MethodWriter(cw, ACC_PUBLIC, "writeUnsorted", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));
// obj
mw.visitVarInsn(ALOAD, Context.obj);
// serializer
mw.visitTypeInsn(CHECKCAST, type(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteMethod(clazz, mw, unsortedGetters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(7, context.variantIndex + 2);
mw.visitEnd();
}
// 2 writeAsArrayNonContext
for (int i = 0; i < 3; ++i) {
String methodName;
boolean nonContext = DisableCircularReferenceDetect;
boolean writeDirect = false;
if (i == 0) {
methodName = "writeAsArray";
writeDirect = true;
} else if (i == 1) {
methodName = "writeAsArrayNormal";
} else {
writeDirect = true;
nonContext = true;
methodName = "writeAsArrayNonContext";
}
Context context = new Context(getters, beanInfo, classNameType, writeDirect, nonContext);
mw = new MethodWriter(cw, ACC_PUBLIC, methodName, "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));
// obj
mw.visitVarInsn(ALOAD, Context.obj);
// serializer
mw.visitTypeInsn(CHECKCAST, type(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteAsArray(clazz, mw, getters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(7, context.variantIndex + 2);
mw.visitEnd();
}
byte[] code = cw.toByteArray();
Class<?> serializerClass = classLoader.defineClassPublic(classNameFull, code, 0, code.length);
Constructor<?> constructor = serializerClass.getConstructor(SerializeBeanInfo.class);
Object instance = constructor.newInstance(beanInfo);
return (JavaBeanSerializer) instance;
}
Aggregations