All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.macrocloud.kernel.toolkit.convert.BaseConverter Maven / Gradle / Ivy

There is a newer version: 1.1.0-RELEASE
Show newest version
package org.macrocloud.kernel.toolkit.convert;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.macrocloud.kernel.toolkit.function.CheckedFunction;
import org.macrocloud.kernel.toolkit.utils.ClassUtil;
import org.macrocloud.kernel.toolkit.utils.ConvertUtil;
import org.macrocloud.kernel.toolkit.utils.ReflectUtil;
import org.macrocloud.kernel.toolkit.utils.Unchecked;
import org.springframework.cglib.core.Converter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


/**
 * 组合 spring cglib Converter 和 spring ConversionService.
 *
 * @author macro
 */

/** The Constant log. */

/** The Constant log. */
@Slf4j

/**
 * Instantiates a new base converter.
 *
 * @param sourceClazz the source clazz
 * @param targetClazz the target clazz
 */
@AllArgsConstructor
public class BaseConverter implements Converter {
	
	/** The Constant TYPE_CACHE. */
	private static final ConcurrentMap TYPE_CACHE = new ConcurrentHashMap<>();
	
	/** The source clazz. */
	private final Class sourceClazz;
	
	/** The target clazz. */
	private final Class targetClazz;

	/**
	 * cglib convert.
	 *
	 * @param value     源对象属性
	 * @param target    目标对象属性类
	 * @param fieldName 目标的field名,原为 set 方法名,BladeBeanCopier 里做了更改
	 * @return {Object}
	 */
	@Override
	@Nullable
	public Object convert(Object value, Class target, final Object fieldName) {
		if (value == null) {
			return null;
		}
		// 类型一样,不需要转换
		if (ClassUtil.isAssignableValue(target, value)) {
			return value;
		}
		try {
			TypeDescriptor targetDescriptor = BaseConverter.getTypeDescriptor(targetClazz, (String) fieldName);
			// 1. 判断 sourceClazz 为 Map
			if (Map.class.isAssignableFrom(sourceClazz)) {
				return ConvertUtil.convert(value, targetDescriptor);
			} else {
				TypeDescriptor sourceDescriptor = BaseConverter.getTypeDescriptor(sourceClazz, (String) fieldName);
				return ConvertUtil.convert(value, sourceDescriptor, targetDescriptor);
			}
		} catch (Throwable e) {
			log.warn("BladeConverter error", e);
			return null;
		}
	}

	/**
	 * Gets the type descriptor.
	 *
	 * @param clazz the clazz
	 * @param fieldName the field name
	 * @return the type descriptor
	 */
	private static TypeDescriptor getTypeDescriptor(final Class clazz, final String fieldName) {
		String srcCacheKey = clazz.getName() + fieldName;
		// 忽略抛出异常的函数,定义完整泛型,避免编译问题
		CheckedFunction uncheckedFunction = (key) -> {
			// 这里 property 理论上不会为 null
			Field field = ReflectUtil.getField(clazz, fieldName);
			if (field == null) {
				throw new NoSuchFieldException(fieldName);
			}
			return new TypeDescriptor(field);
		};
		return TYPE_CACHE.computeIfAbsent(srcCacheKey, Unchecked.function(uncheckedFunction));
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy