Search in sources :

Example 1 with Module

use of com.alibaba.fastjson.spi.Module 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;
}
Also used : Charset(java.nio.charset.Charset) JSONType(com.alibaba.fastjson.annotation.JSONType) Module(com.alibaba.fastjson.spi.Module) JSONType(com.alibaba.fastjson.annotation.JSONType) IdentityHashMap(com.alibaba.fastjson.util.IdentityHashMap)

Example 2 with Module

use of com.alibaba.fastjson.spi.Module in project fastjson by alibaba.

the class ParserConfig method getDeserializer.

public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
    ObjectDeserializer deserializer = get(type);
    if (deserializer == null && type instanceof ParameterizedTypeImpl) {
        Type innerType = TypeReference.intern((ParameterizedTypeImpl) type);
        deserializer = get(innerType);
    }
    if (deserializer != null) {
        return deserializer;
    }
    if (type == null) {
        type = clazz;
    }
    deserializer = get(type);
    if (deserializer != null) {
        return deserializer;
    }
    {
        JSONType annotation = TypeUtils.getAnnotation(clazz, JSONType.class);
        if (annotation != null) {
            Class<?> mappingTo = annotation.mappingTo();
            if (mappingTo != Void.class) {
                return getDeserializer(mappingTo, mappingTo);
            }
        }
    }
    if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
        deserializer = get(clazz);
    }
    if (deserializer != null) {
        return deserializer;
    }
    for (Module module : modules) {
        deserializer = module.createDeserializer(this, clazz);
        if (deserializer != null) {
            putDeserializer(type, deserializer);
            return deserializer;
        }
    }
    String className = clazz.getName();
    className = className.replace('$', '.');
    if (// 
    className.startsWith("java.awt.") && AwtCodec.support(clazz)) {
        if (!awtError) {
            String[] names = new String[] { "java.awt.Point", "java.awt.Font", "java.awt.Rectangle", "java.awt.Color" };
            try {
                for (String name : names) {
                    if (name.equals(className)) {
                        putDeserializer(Class.forName(name), deserializer = AwtCodec.instance);
                        return deserializer;
                    }
                }
            } catch (Throwable e) {
                // skip
                awtError = true;
            }
            deserializer = AwtCodec.instance;
        }
    }
    if (!jdk8Error) {
        try {
            if (className.startsWith("java.time.")) {
                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.ZoneId", "java.time.Period", "java.time.Duration", "java.time.Instant" };
                for (String name : names) {
                    if (name.equals(className)) {
                        putDeserializer(Class.forName(name), deserializer = Jdk8DateCodec.instance);
                        return deserializer;
                    }
                }
            } else if (className.startsWith("java.util.Optional")) {
                String[] names = new String[] { "java.util.Optional", "java.util.OptionalDouble", "java.util.OptionalInt", "java.util.OptionalLong" };
                for (String name : names) {
                    if (name.equals(className)) {
                        putDeserializer(Class.forName(name), deserializer = OptionalCodec.instance);
                        return deserializer;
                    }
                }
            }
        } catch (Throwable e) {
            // skip
            jdk8Error = true;
        }
    }
    if (!jodaError) {
        try {
            if (className.startsWith("org.joda.time.")) {
                String[] names = new String[] { "org.joda.time.DateTime", "org.joda.time.LocalDate", "org.joda.time.LocalDateTime", "org.joda.time.LocalTime", "org.joda.time.Instant", "org.joda.time.Period", "org.joda.time.Duration", "org.joda.time.DateTimeZone", "org.joda.time.format.DateTimeFormatter" };
                for (String name : names) {
                    if (name.equals(className)) {
                        putDeserializer(Class.forName(name), deserializer = JodaCodec.instance);
                        return deserializer;
                    }
                }
            }
        } catch (Throwable e) {
            // skip
            jodaError = 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)) {
                    putDeserializer(Class.forName(name), deserializer = GuavaCodec.instance);
                    return deserializer;
                }
            }
        } catch (ClassNotFoundException e) {
            // skip
            guavaError = true;
        }
    }
    if (className.equals("java.nio.ByteBuffer")) {
        putDeserializer(clazz, deserializer = ByteBufferCodec.instance);
    }
    if (className.equals("java.nio.file.Path")) {
        putDeserializer(clazz, deserializer = MiscCodec.instance);
    }
    if (clazz == Map.Entry.class) {
        putDeserializer(clazz, deserializer = MiscCodec.instance);
    }
    if (className.equals("org.javamoney.moneta.Money")) {
        putDeserializer(clazz, deserializer = MonetaCodec.instance);
    }
    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    try {
        for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) {
            for (Type forType : autowired.getAutowiredFor()) {
                putDeserializer(forType, autowired);
            }
        }
    } catch (Exception ex) {
    // skip
    }
    if (deserializer == null) {
        deserializer = get(type);
    }
    if (deserializer != null) {
        return deserializer;
    }
    if (clazz.isEnum()) {
        if (jacksonCompatible) {
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (TypeUtils.isJacksonCreator(method)) {
                    deserializer = createJavaBeanDeserializer(clazz, type);
                    putDeserializer(type, deserializer);
                    return deserializer;
                }
            }
        }
        Class mixInType = (Class) JSON.getMixInAnnotations(clazz);
        Class<?> deserClass = null;
        JSONType jsonType = TypeUtils.getAnnotation(mixInType != null ? mixInType : clazz, JSONType.class);
        if (jsonType != null) {
            deserClass = jsonType.deserializer();
            try {
                deserializer = (ObjectDeserializer) deserClass.newInstance();
                putDeserializer(clazz, deserializer);
                return deserializer;
            } catch (Throwable error) {
            // skip
            }
        }
        Method jsonCreatorMethod = null;
        if (mixInType != null) {
            Method mixedCreator = getEnumCreator(mixInType, clazz);
            if (mixedCreator != null) {
                try {
                    jsonCreatorMethod = clazz.getMethod(mixedCreator.getName(), mixedCreator.getParameterTypes());
                } catch (Exception e) {
                // skip
                }
            }
        } else {
            jsonCreatorMethod = getEnumCreator(clazz, clazz);
        }
        if (jsonCreatorMethod != null) {
            deserializer = new EnumCreatorDeserializer(jsonCreatorMethod);
            putDeserializer(clazz, deserializer);
            return deserializer;
        }
        deserializer = getEnumDeserializer(clazz);
    } else if (clazz.isArray()) {
        deserializer = ObjectArrayCodec.instance;
    } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) {
        deserializer = CollectionCodec.instance;
    } else if (Collection.class.isAssignableFrom(clazz)) {
        deserializer = CollectionCodec.instance;
    } else if (Map.class.isAssignableFrom(clazz)) {
        deserializer = MapDeserializer.instance;
    } else if (Throwable.class.isAssignableFrom(clazz)) {
        deserializer = new ThrowableDeserializer(this, clazz);
    } else if (PropertyProcessable.class.isAssignableFrom(clazz)) {
        deserializer = new PropertyProcessableDeserializer((Class<PropertyProcessable>) clazz);
    } else if (clazz == InetAddress.class) {
        deserializer = MiscCodec.instance;
    } else {
        deserializer = createJavaBeanDeserializer(clazz, type);
    }
    putDeserializer(type, deserializer);
    return deserializer;
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) AccessControlException(java.security.AccessControlException) JSONType(com.alibaba.fastjson.annotation.JSONType) JSONType(com.alibaba.fastjson.annotation.JSONType) Module(com.alibaba.fastjson.spi.Module) ConcurrentMap(java.util.concurrent.ConcurrentMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IdentityHashMap(com.alibaba.fastjson.util.IdentityHashMap) InetAddress(java.net.InetAddress)

Aggregations

JSONType (com.alibaba.fastjson.annotation.JSONType)2 Module (com.alibaba.fastjson.spi.Module)2 IdentityHashMap (com.alibaba.fastjson.util.IdentityHashMap)2 InetAddress (java.net.InetAddress)1 Charset (java.nio.charset.Charset)1 AccessControlException (java.security.AccessControlException)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1