package com.qianwen.core.tool.beans; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.security.ProtectionDomain; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.qianwen.core.tool.utils.BeanUtil; import com.qianwen.core.tool.utils.ClassUtil; import com.qianwen.core.tool.utils.ReflectUtil; import com.qianwen.core.tool.utils.StringUtil; import org.springframework.asm.ClassVisitor; import org.springframework.asm.Label; import org.springframework.asm.Type; import org.springframework.cglib.core.AbstractClassGenerator; import org.springframework.cglib.core.ClassEmitter; import org.springframework.cglib.core.CodeEmitter; import org.springframework.cglib.core.Constants; import org.springframework.cglib.core.Converter; import org.springframework.cglib.core.EmitUtils; import org.springframework.cglib.core.Local; import org.springframework.cglib.core.MethodInfo; import org.springframework.cglib.core.ReflectUtils; import org.springframework.cglib.core.Signature; import org.springframework.cglib.core.TypeUtils; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /* loaded from: blade-core-tool-9.3.0.0-SNAPSHOT.jar:org/springblade/core/tool/beans/BladeBeanCopier.class */ public abstract class BladeBeanCopier { private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter"); private static final Type BEAN_COPIER = TypeUtils.parseType(BladeBeanCopier.class.getName()); private static final Type BEAN_MAP = TypeUtils.parseType(Map.class.getName()); private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER}); private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)"); private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object)"); private static final Type CLASS_UTILS = TypeUtils.parseType(ClassUtils.class.getName()); private static final Signature IS_ASSIGNABLE_VALUE = TypeUtils.parseSignature("boolean isAssignableValue(Class, Object)"); private static final ConcurrentMap BEAN_COPIER_MAP = new ConcurrentHashMap(); public abstract void copy(Object from, Object to, @Nullable Converter converter); public static BladeBeanCopier create(Class source, Class target, boolean useConverter) { return create(source, target, useConverter, false); } public static BladeBeanCopier create(Class source, Class target, boolean useConverter, boolean nonNull) { BladeBeanCopierKey copierKey = new BladeBeanCopierKey(source, target, useConverter, nonNull); return BEAN_COPIER_MAP.computeIfAbsent(copierKey, key -> { Generator gen = new Generator(); gen.setSource(key.getSource()); gen.setTarget(key.getTarget()); gen.setUseConverter(key.isUseConverter()); gen.setNonNull(key.isNonNull()); return gen.m3create((Object) key); }); } /* loaded from: blade-core-tool-9.3.0.0-SNAPSHOT.jar:org/springblade/core/tool/beans/BladeBeanCopier$Generator.class */ public static class Generator extends AbstractClassGenerator { private static final AbstractClassGenerator.Source SOURCE = new AbstractClassGenerator.Source(BladeBeanCopier.class.getName()); private Class source; private Class target; private boolean useConverter; private boolean nonNull; Generator() { super(SOURCE); } public void setSource(Class source) { if (!Modifier.isPublic(source.getModifiers())) { setNamePrefix(source.getName()); } this.source = source; } public void setTarget(Class target) { if (!Modifier.isPublic(target.getModifiers())) { setNamePrefix(target.getName()); } this.target = target; } public void setUseConverter(boolean useConverter) { this.useConverter = useConverter; } public void setNonNull(boolean nonNull) { this.nonNull = nonNull; } protected ClassLoader getDefaultClassLoader() { return this.target.getClassLoader(); } protected ProtectionDomain getProtectionDomain() { return ReflectUtils.getProtectionDomain(this.source); } /* renamed from: create */ public BladeBeanCopier m3create(Object key) { return (BladeBeanCopier) super.create(key); } public void generateClass(ClassVisitor v) { Type sourceType = Type.getType(this.source); Type targetType = Type.getType(this.target); ClassEmitter ce = new ClassEmitter(v); ce.begin_class(46, 1, getClassName(), BladeBeanCopier.BEAN_COPIER, (Type[]) null, ""); EmitUtils.null_constructor(ce); CodeEmitter e = ce.begin_method(1, BladeBeanCopier.COPY, (Type[]) null); if (Map.class.isAssignableFrom(this.source)) { generateClassFormMap(ce, e, sourceType, targetType); return; } PropertyDescriptor[] getters = ReflectUtil.getBeanGetters(this.source); PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(this.target); Map names = new HashMap<>(16); for (PropertyDescriptor getter : getters) { names.put(getter.getName(), getter); } Local targetLocal = e.make_local(); Local sourceLocal = e.make_local(); e.load_arg(1); e.checkcast(targetType); e.store_local(targetLocal); e.load_arg(0); e.checkcast(sourceType); e.store_local(sourceLocal); for (PropertyDescriptor setter : setters) { String propName = setter.getName(); CopyProperty targetIgnoreCopy = (CopyProperty) ReflectUtil.getAnnotation(this.target, propName, CopyProperty.class); if (targetIgnoreCopy != null) { if (!targetIgnoreCopy.ignore()) { String aliasTargetPropName = targetIgnoreCopy.value(); if (StringUtil.isNotBlank(aliasTargetPropName)) { propName = aliasTargetPropName; } } } PropertyDescriptor getter2 = names.get(propName); if (getter2 != null) { MethodInfo read = ReflectUtils.getMethodInfo(getter2.getReadMethod()); Method writeMethod = setter.getWriteMethod(); MethodInfo write = ReflectUtils.getMethodInfo(writeMethod); Type returnType = read.getSignature().getReturnType(); Type setterType = write.getSignature().getArgumentTypes()[0]; Class getterPropertyType = getter2.getPropertyType(); Class setterPropertyType = setter.getPropertyType(); Label l0 = e.make_label(); if (ClassUtil.isAssignable(setterPropertyType, getterPropertyType)) { e.load_local(targetLocal); e.load_local(sourceLocal); e.invoke(read); boolean getterIsPrimitive = getterPropertyType.isPrimitive(); boolean setterIsPrimitive = setterPropertyType.isPrimitive(); if (this.nonNull) { e.box(returnType); Local var = e.make_local(); e.store_local(var); e.load_local(var); e.ifnull(l0); e.load_local(targetLocal); e.load_local(var); e.unbox_or_zero(setterType); } else { if (getterIsPrimitive && !setterIsPrimitive) { e.box(returnType); } if (!getterIsPrimitive && setterIsPrimitive) { e.unbox_or_zero(setterType); } } invokeWrite(e, write, writeMethod, this.nonNull, l0); } else if (this.useConverter) { e.load_local(targetLocal); e.load_arg(2); e.load_local(sourceLocal); e.invoke(read); e.box(returnType); if (this.nonNull) { Local var2 = e.make_local(); e.store_local(var2); e.load_local(var2); e.ifnull(l0); e.load_local(targetLocal); e.load_arg(2); e.load_local(var2); } EmitUtils.load_class(e, setterType); e.push(propName); e.invoke_interface(BladeBeanCopier.CONVERTER, BladeBeanCopier.CONVERT); e.unbox_or_zero(setterType); invokeWrite(e, write, writeMethod, this.nonNull, l0); } } } e.return_value(); e.end_method(); ce.end_class(); } private static void invokeWrite(CodeEmitter e, MethodInfo write, Method writeMethod, boolean nonNull, Label l0) { Class returnType = writeMethod.getReturnType(); e.invoke(write); if (!returnType.equals(Void.TYPE)) { e.pop(); } if (nonNull) { e.visitLabel(l0); } } protected Object firstInstance(Class type) { return BeanUtil.newInstance(type); } protected Object nextInstance(Object instance) { return instance; } public void generateClassFormMap(ClassEmitter ce, CodeEmitter e, Type sourceType, Type targetType) { PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(this.target); Local targetLocal = e.make_local(); Local sourceLocal = e.make_local(); e.load_arg(1); e.checkcast(targetType); e.store_local(targetLocal); e.load_arg(0); e.checkcast(sourceType); e.store_local(sourceLocal); Type mapBox = Type.getType(Object.class); for (PropertyDescriptor setter : setters) { String propName = setter.getName(); CopyProperty targetIgnoreCopy = (CopyProperty) ReflectUtil.getAnnotation(this.target, propName, CopyProperty.class); if (targetIgnoreCopy != null) { if (!targetIgnoreCopy.ignore()) { String aliasTargetPropName = targetIgnoreCopy.value(); if (StringUtil.isNotBlank(aliasTargetPropName)) { propName = aliasTargetPropName; } } } Method writeMethod = setter.getWriteMethod(); MethodInfo write = ReflectUtils.getMethodInfo(writeMethod); Type setterType = write.getSignature().getArgumentTypes()[0]; e.load_local(targetLocal); e.load_local(sourceLocal); e.push(propName); e.invoke_interface(BladeBeanCopier.BEAN_MAP, BladeBeanCopier.BEAN_MAP_GET); e.box(mapBox); Local var = e.make_local(); e.store_local(var); e.load_local(var); Label l0 = e.make_label(); e.ifnull(l0); EmitUtils.load_class(e, setterType); e.load_local(var); e.invoke_static(BladeBeanCopier.CLASS_UTILS, BladeBeanCopier.IS_ASSIGNABLE_VALUE); Label l1 = new Label(); Class returnType = writeMethod.getReturnType(); if (this.useConverter) { e.if_jump(153, l1); e.load_local(targetLocal); e.load_local(var); e.unbox_or_zero(setterType); e.invoke(write); if (!returnType.equals(Void.TYPE)) { e.pop(); } e.goTo(l0); e.visitLabel(l1); e.load_local(targetLocal); e.load_arg(2); e.load_local(var); EmitUtils.load_class(e, setterType); e.push(propName); e.invoke_interface(BladeBeanCopier.CONVERTER, BladeBeanCopier.CONVERT); e.unbox_or_zero(setterType); e.invoke(write); } else { e.if_jump(153, l0); e.load_local(targetLocal); e.load_local(var); e.unbox_or_zero(setterType); e.invoke(write); } if (!returnType.equals(Void.TYPE)) { e.pop(); } e.visitLabel(l0); } e.return_value(); e.end_method(); ce.end_class(); } } }