From 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a Mon Sep 17 00:00:00 2001
From: xiejun <xiejun@vci-tech.com>
Date: 星期五, 01 十一月 2024 15:11:19 +0800
Subject: [PATCH] Revert "集成获取mdm分发通用数据格式接口集成"

---
 Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/beans/BladeBeanCopier.java |  405 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 405 insertions(+), 0 deletions(-)

diff --git a/Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/beans/BladeBeanCopier.java b/Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/beans/BladeBeanCopier.java
new file mode 100644
index 0000000..0dc0c33
--- /dev/null
+++ b/Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/beans/BladeBeanCopier.java
@@ -0,0 +1,405 @@
+/*
+ *      Copyright (c) 2018-2028, DreamLu All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: DreamLu 鍗㈡槬姊� (596392912@qq.com)
+ */
+
+package org.springblade.core.tool.beans;
+
+
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.ClassUtil;
+import org.springblade.core.tool.utils.ReflectUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springframework.asm.ClassVisitor;
+import org.springframework.asm.Label;
+import org.springframework.asm.Opcodes;
+import org.springframework.asm.Type;
+import org.springframework.cglib.core.*;
+import org.springframework.lang.Nullable;
+import org.springframework.util.ClassUtils;
+
+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;
+
+/**
+ * spring cglib 榄旀敼
+ *
+ * <p>
+ *     1. 鏀寔閾惧紡 bean锛屾敮鎸� map
+ *     2. ClassLoader 璺� target 淇濇寔涓�鑷�
+ * </p>
+ *
+ * @author L.cm
+ */
+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)");
+	/**
+	 * The map to store {@link BladeBeanCopier} of source type and class type for copy.
+	 */
+	private static final ConcurrentMap<BladeBeanCopierKey, BladeBeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>();
+
+	public static BladeBeanCopier create(Class source, Class target, boolean useConverter) {
+		return BladeBeanCopier.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);
+		// 鍒╃敤 ConcurrentMap 缂撳瓨 鎻愰珮鎬ц兘锛屾帴杩� 鐩存帴 get set
+		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.create(key);
+		});
+	}
+
+	/**
+	 * Bean copy
+	 *
+	 * @param from from Bean
+	 * @param to to Bean
+	 * @param converter Converter
+	 */
+	abstract public void copy(Object from, Object to, @Nullable Converter converter);
+
+	public static class Generator extends AbstractClassGenerator {
+		private static final Source SOURCE = new 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;
+		}
+
+		@Override
+		protected ClassLoader getDefaultClassLoader() {
+			// L.cm 淇濊瘉 鍜� 杩斿洖浣跨敤鍚屼竴涓� ClassLoader
+			return target.getClassLoader();
+		}
+
+		@Override
+		protected ProtectionDomain getProtectionDomain() {
+			return ReflectUtils.getProtectionDomain(source);
+		}
+
+		@Override
+		public BladeBeanCopier create(Object key) {
+			return (BladeBeanCopier) super.create(key);
+		}
+
+		@Override
+		public void generateClass(ClassVisitor v) {
+			Type sourceType = Type.getType(source);
+			Type targetType = Type.getType(target);
+			ClassEmitter ce = new ClassEmitter(v);
+			ce.begin_class(Constants.V1_2,
+				Constants.ACC_PUBLIC,
+				getClassName(),
+				BEAN_COPIER,
+				null,
+				Constants.SOURCE_FILE);
+
+			EmitUtils.null_constructor(ce);
+			CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null);
+
+			// map 鍗曠嫭澶勭悊
+			if (Map.class.isAssignableFrom(source)) {
+				generateClassFormMap(ce, e, sourceType, targetType);
+				return;
+			}
+
+			// 2018.12.27 by L.cm 鏀寔閾惧紡 bean
+			// 娉ㄦ剰锛氭澶勯渶鍏煎閾惧紡bean 浣跨敤浜� spring 鐨勬柟娉曪紝姣旇緝鑰楁椂
+			PropertyDescriptor[] getters = ReflectUtil.getBeanGetters(source);
+			PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(target);
+			Map<String, PropertyDescriptor> 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 = ReflectUtil.getAnnotation(target, propName, CopyProperty.class);
+				// set 涓婃湁蹇界暐鐨� 娉ㄨВ
+				if (targetIgnoreCopy != null) {
+					if (targetIgnoreCopy.ignore()) {
+						continue;
+					}
+					// 娉ㄨВ涓婄殑鍒悕锛屽鏋滃埆鍚嶄笉涓虹┖锛屼娇鐢ㄥ埆鍚�
+					String aliasTargetPropName = targetIgnoreCopy.value();
+					if (StringUtil.isNotBlank(aliasTargetPropName)) {
+						propName = aliasTargetPropName;
+					}
+				}
+				// 鎵惧埌瀵瑰簲鐨� get
+				PropertyDescriptor getter = names.get(propName);
+				// 娌℃湁 get 璺冲嚭
+				if (getter == null) {
+					continue;
+				}
+
+				MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
+				Method writeMethod = setter.getWriteMethod();
+				MethodInfo write = ReflectUtils.getMethodInfo(writeMethod);
+				Type returnType = read.getSignature().getReturnType();
+				Type setterType = write.getSignature().getArgumentTypes()[0];
+				Class<?> getterPropertyType = getter.getPropertyType();
+				Class<?> setterPropertyType = setter.getPropertyType();
+
+				// L.cm 2019.01.12 浼樺寲閫昏緫锛屽厛鍒ゆ柇绫诲瀷锛岀被鍨嬩竴鑷寸洿鎺� set锛屼笉鍚屽啀鍒ゆ柇 鏄惁 绫诲瀷杞崲
+				// nonNull Label
+				Label l0 = e.make_label();
+				// 鍒ゆ柇绫诲瀷鏄惁涓�鑷达紝鍖呮嫭 鍖呰绫诲瀷
+				if (ClassUtil.isAssignable(setterPropertyType, getterPropertyType)) {
+					// 2018.12.27 by L.cm 鏀寔閾惧紡 bean
+					e.load_local(targetLocal);
+					e.load_local(sourceLocal);
+					e.invoke(read);
+					boolean getterIsPrimitive = getterPropertyType.isPrimitive();
+					boolean setterIsPrimitive = setterPropertyType.isPrimitive();
+
+					if (nonNull) {
+						// 闇�瑕佽惤鏍堬紝寮哄埗瑁呯
+						e.box(returnType);
+						Local var = e.make_local();
+						e.store_local(var);
+						e.load_local(var);
+						// nonNull Label
+						e.ifnull(l0);
+						e.load_local(targetLocal);
+						e.load_local(var);
+						// 闇�瑕佽惤鏍堬紝寮哄埗鎷嗙
+						e.unbox_or_zero(setterType);
+					} else {
+						// 濡傛灉 get 涓哄師濮嬬被鍨嬶紝闇�瑕佽绠�
+						if (getterIsPrimitive && !setterIsPrimitive) {
+							e.box(returnType);
+						}
+						// 濡傛灉 set 涓哄師濮嬬被鍨嬶紝闇�瑕佹媶绠�
+						if (!getterIsPrimitive && setterIsPrimitive) {
+							e.unbox_or_zero(setterType);
+						}
+					}
+
+					// 鏋勯�� set 鏂规硶
+					invokeWrite(e, write, writeMethod, nonNull, l0);
+				} else if (useConverter) {
+					e.load_local(targetLocal);
+					e.load_arg(2);
+					e.load_local(sourceLocal);
+					e.invoke(read);
+					e.box(returnType);
+
+					if (nonNull) {
+						Local var = e.make_local();
+						e.store_local(var);
+						e.load_local(var);
+						e.ifnull(l0);
+						e.load_local(targetLocal);
+						e.load_arg(2);
+						e.load_local(var);
+					}
+
+					EmitUtils.load_class(e, setterType);
+					// 鏇存敼鎴愪簡灞炴�у悕锛屼箣鍓嶆槸 set 鏂规硶鍚�
+					e.push(propName);
+					e.invoke_interface(CONVERTER, CONVERT);
+					e.unbox_or_zero(setterType);
+
+					// 鏋勯�� set 鏂规硶
+					invokeWrite(e, write, writeMethod, 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) {
+			// 杩斿洖鍊硷紝鍒ゆ柇 閾惧紡 bean
+			Class<?> returnType = writeMethod.getReturnType();
+			e.invoke(write);
+			// 閾惧紡 bean锛屾湁杩斿洖鍊奸渶瑕� pop
+			if (!returnType.equals(Void.TYPE)) {
+				e.pop();
+			}
+			if (nonNull) {
+				e.visitLabel(l0);
+			}
+		}
+
+		@Override
+		protected Object firstInstance(Class type) {
+			return BeanUtil.newInstance(type);
+		}
+
+		@Override
+		protected Object nextInstance(Object instance) {
+			return instance;
+		}
+
+		/**
+		 * 澶勭悊 map 鐨� copy
+		 * @param ce ClassEmitter
+		 * @param e CodeEmitter
+		 * @param sourceType sourceType
+		 * @param targetType targetType
+		 */
+		public void generateClassFormMap(ClassEmitter ce, CodeEmitter e, Type sourceType, Type targetType) {
+			// 2018.12.27 by L.cm 鏀寔閾惧紡 bean
+			PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(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();
+
+				// set 涓婃湁蹇界暐鐨� 娉ㄨВ
+				CopyProperty targetIgnoreCopy = ReflectUtil.getAnnotation(target, propName, CopyProperty.class);
+				if (targetIgnoreCopy != null) {
+					if (targetIgnoreCopy.ignore()) {
+						continue;
+					}
+					// 娉ㄨВ涓婄殑鍒悕
+					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);
+				// 鎵ц map get
+				e.invoke_interface(BEAN_MAP, BEAN_MAP_GET);
+				// box 瑁呯锛岄伩鍏� array[] 鏁扮粍闂
+				e.box(mapBox);
+
+				// 鐢熸垚鍙橀噺
+				Local var = e.make_local();
+				e.store_local(var);
+				e.load_local(var);
+
+				// 鍏堝垽鏂� 涓嶄负null锛岀劧鍚庡仛绫诲瀷鍒ゆ柇
+				Label l0 = e.make_label();
+				e.ifnull(l0);
+				EmitUtils.load_class(e, setterType);
+				e.load_local(var);
+				// ClassUtils.isAssignableValue(Integer.class, id)
+				e.invoke_static(CLASS_UTILS, IS_ASSIGNABLE_VALUE);
+				Label l1 = new Label();
+				// 杩斿洖鍊硷紝鍒ゆ柇 閾惧紡 bean
+				Class<?> returnType = writeMethod.getReturnType();
+				if (useConverter) {
+					e.if_jump(Opcodes.IFEQ, 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(CONVERTER, CONVERT);
+					e.unbox_or_zero(setterType);
+					e.invoke(write);
+				} else {
+					e.if_jump(Opcodes.IFEQ, l0);
+					e.load_local(targetLocal);
+					e.load_local(var);
+					e.unbox_or_zero(setterType);
+					e.invoke(write);
+				}
+				// 杩斿洖鍊硷紝鍒ゆ柇 閾惧紡 bean
+				if (!returnType.equals(Void.TYPE)) {
+					e.pop();
+				}
+				e.visitLabel(l0);
+			}
+			e.return_value();
+			e.end_method();
+			ce.end_class();
+		}
+	}
+}

--
Gitblit v1.9.3