001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.handler;
017
018import com.alibaba.fastjson.JSON;
019import com.alibaba.fastjson.serializer.SerializerFeature;
020
021import java.lang.reflect.ParameterizedType;
022import java.lang.reflect.Type;
023import java.util.Arrays;
024import java.util.Collection;
025import java.util.Objects;
026
027/**
028 * @author michael
029 */
030public class FastjsonTypeHandler extends BaseJsonTypeHandler<Object> {
031
032    private final Class<?> propertyType;
033    private Class<?> genericType;
034    private Type type;
035
036    public FastjsonTypeHandler(Class<?> propertyType) {
037        this.propertyType = propertyType;
038    }
039
040    public FastjsonTypeHandler(Class<?> propertyType, Class<?> genericType) {
041        this.propertyType = propertyType;
042        this.genericType = genericType;
043        this.type = new ParameterizedTypeImpl(propertyType, genericType);
044    }
045
046    @Override
047    protected Object parseJson(String json) {
048        if (genericType != null && Collection.class.isAssignableFrom(propertyType)) {
049            return JSON.parseObject(json, type);
050        } else {
051            return JSON.parseObject(json, propertyType);
052        }
053    }
054
055    @Override
056    protected String toJson(Object object) {
057        return JSON.toJSONString(object, SerializerFeature.WriteMapNullValue,
058            SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
059    }
060
061
062    public static class ParameterizedTypeImpl implements ParameterizedType {
063
064        private final Type[] actualTypeArguments;
065        private final Type ownerType;
066        private final Type rawType;
067
068        public ParameterizedTypeImpl(Type rawType, Type... actualTypeArguments) {
069            this.rawType = rawType;
070            this.actualTypeArguments = actualTypeArguments;
071            this.ownerType = null;
072        }
073
074        @Override
075        public Type[] getActualTypeArguments() {
076            return this.actualTypeArguments;
077        }
078
079        @Override
080        public Type getOwnerType() {
081            return this.ownerType;
082        }
083
084        @Override
085        public Type getRawType() {
086            return this.rawType;
087        }
088
089        @Override
090        public boolean equals(Object o) {
091            if (this == o) {
092                return true;
093            } else if (o != null && this.getClass() == o.getClass()) {
094                ParameterizedTypeImpl that = (ParameterizedTypeImpl) o;
095                if (!Arrays.equals(this.actualTypeArguments, that.actualTypeArguments)) {
096                    return false;
097                } else {
098                    if (this.ownerType != null) {
099                        if (this.ownerType.equals(that.ownerType)) {
100                            return Objects.equals(this.rawType, that.rawType);
101                        }
102                    } else if (that.ownerType == null) {
103                        return Objects.equals(this.rawType, that.rawType);
104                    }
105
106                    return false;
107                }
108            } else {
109                return false;
110            }
111        }
112
113        @Override
114        public int hashCode() {
115            int result = this.actualTypeArguments != null ? Arrays.hashCode(this.actualTypeArguments) : 0;
116            result = 31 * result + (this.ownerType != null ? this.ownerType.hashCode() : 0);
117            result = 31 * result + (this.rawType != null ? this.rawType.hashCode() : 0);
118            return result;
119        }
120    }
121
122
123}