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;
025
026/**
027 * @author michael
028 */
029public class FastjsonTypeHandler extends BaseJsonTypeHandler<Object> {
030
031    private final Class<?> propertyType;
032    private Class<?> genericType;
033    private Type type;
034
035    public FastjsonTypeHandler(Class<?> propertyType) {
036        this.propertyType = propertyType;
037    }
038
039    public FastjsonTypeHandler(Class<?> propertyType, Class<?> genericType) {
040        this.propertyType = propertyType;
041        this.genericType = genericType;
042        this.type = new ParameterizedTypeImpl(propertyType, genericType);
043    }
044
045    @Override
046    protected Object parseJson(String json) {
047        if (genericType != null && Collection.class.isAssignableFrom(propertyType)) {
048            return JSON.parseObject(json, type);
049        } else {
050            return JSON.parseObject(json, propertyType);
051        }
052    }
053
054    @Override
055    protected String toJson(Object object) {
056        return JSON.toJSONString(object, SerializerFeature.WriteMapNullValue,
057            SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
058    }
059
060
061    public static class ParameterizedTypeImpl implements ParameterizedType {
062
063        private final Type[] actualTypeArguments;
064        private final Type ownerType;
065        private final Type rawType;
066
067        public ParameterizedTypeImpl(Type rawType, Type... actualTypeArguments) {
068            this.rawType = rawType;
069            this.actualTypeArguments = actualTypeArguments;
070            this.ownerType = null;
071        }
072
073        @Override
074        public Type[] getActualTypeArguments() {
075            return this.actualTypeArguments;
076        }
077
078        @Override
079        public Type getOwnerType() {
080            return this.ownerType;
081        }
082
083        @Override
084        public Type getRawType() {
085            return this.rawType;
086        }
087
088        @Override
089        public boolean equals(Object o) {
090            if (this == o) {
091                return true;
092            } else if (o != null && this.getClass() == o.getClass()) {
093                ParameterizedTypeImpl that = (ParameterizedTypeImpl) o;
094                if (!Arrays.equals(this.actualTypeArguments, that.actualTypeArguments)) {
095                    return false;
096                } else {
097                    if (this.ownerType != null) {
098                        if (this.ownerType.equals(that.ownerType)) {
099                            return this.rawType != null ? this.rawType.equals(that.rawType) : that.rawType == null;
100                        }
101                    } else if (that.ownerType == null) {
102                        return this.rawType != null ? this.rawType.equals(that.rawType) : that.rawType == null;
103                    }
104
105                    return false;
106                }
107            } else {
108                return false;
109            }
110        }
111
112        @Override
113        public int hashCode() {
114            int result = this.actualTypeArguments != null ? Arrays.hashCode(this.actualTypeArguments) : 0;
115            result = 31 * result + (this.ownerType != null ? this.ownerType.hashCode() : 0);
116            result = 31 * result + (this.rawType != null ? this.rawType.hashCode() : 0);
117            return result;
118        }
119    }
120
121
122}