From 57dd3022285466874670210df8e6bac3c2b52003 Mon Sep 17 00:00:00 2001
From: even <827656971@qq.com>
Date: Mon, 28 Apr 2025 16:23:54 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E7=9B=B8=E5=85=B3?=
=?UTF-8?q?=E8=BF=81=E7=A7=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
dependencies/pom.xml | 7 +-
modules/module-ci-process-biz/pom.xml | 4 +
.../context/ApplicationContextContext.java | 18 ++
.../resolver/AnnotationResourceResolver.java | 126 +++++++++
.../module/process/core/util/BeanUtils.java | 42 +++
.../entity/PipelineFollowEntity.java | 20 ++
.../impl/PipelineFollowServiceImpl.java | 97 +++++++
.../definition/dao/PipelineFollowDao.java | 59 ++++
.../process/toolkit/beans/BeanMapper.java | 168 +++++++++++
.../toolkit/beans/annotation/Mapper.java | 18 ++
.../toolkit/beans/annotation/Mappers.java | 12 +
.../toolkit/beans/annotation/Mapping.java | 14 +
.../toolkit/beans/annotation/Mappings.java | 12 +
.../beans/metadata/BeanMapperRegister.java | 267 ++++++++++++++++++
.../toolkit/beans/model/BeanMapping.java | 12 +
.../toolkit/beans/model/FieldMapping.java | 13 +
16 files changed, 888 insertions(+), 1 deletion(-)
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/context/ApplicationContextContext.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/resolver/AnnotationResourceResolver.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/util/BeanUtils.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/entity/PipelineFollowEntity.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/impl/PipelineFollowServiceImpl.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/BeanMapper.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapper.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappers.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapping.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappings.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/metadata/BeanMapperRegister.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/BeanMapping.java
create mode 100644 modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/FieldMapping.java
diff --git a/dependencies/pom.xml b/dependencies/pom.xml
index e94953c..36df6fc 100644
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -85,7 +85,7 @@
2.6.10
2.9.3
2.3.0
-
+ 3.2.1
@@ -676,6 +676,11 @@
${resilience4j-circuitbreaker.version}
+
+ ognl
+ ognl
+ ${ognl.version}
+
diff --git a/modules/module-ci-process-biz/pom.xml b/modules/module-ci-process-biz/pom.xml
index ce94863..ed81253 100644
--- a/modules/module-ci-process-biz/pom.xml
+++ b/modules/module-ci-process-biz/pom.xml
@@ -38,6 +38,10 @@
cd.casic.boot
spring-boot-starter-security
+
+ ognl
+ ognl
+
\ No newline at end of file
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/context/ApplicationContextContext.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/context/ApplicationContextContext.java
new file mode 100644
index 0000000..a33bb12
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/context/ApplicationContextContext.java
@@ -0,0 +1,18 @@
+package cd.casic.module.process.core.context;
+
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class ApplicationContextContext {
+ private static ConfigurableApplicationContext applicationContext;
+
+ public ApplicationContextContext() {
+ }
+
+ public static ConfigurableApplicationContext getApplicationContext() {
+ return applicationContext;
+ }
+
+ public static void setApplicationContext(ConfigurableApplicationContext applicationContext) {
+ ApplicationContextContext.applicationContext = applicationContext;
+ }
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/resolver/AnnotationResourceResolver.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/resolver/AnnotationResourceResolver.java
new file mode 100644
index 0000000..4485c94
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/resolver/AnnotationResourceResolver.java
@@ -0,0 +1,126 @@
+package cd.casic.module.process.core.resolver;
+
+import cd.casic.module.process.core.context.ApplicationContextContext;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.ClassMetadata;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class AnnotationResourceResolver {
+ private static final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ private static final SimpleMetadataReaderFactory register = new SimpleMetadataReaderFactory();
+ private static final StandardEnvironment environment = new StandardEnvironment();
+
+ public AnnotationResourceResolver() {
+ }
+
+ public static Set resolveBeans(String pkgPath, Class extends Annotation> annoClazz) {
+ Set clazzSet = new HashSet();
+ ConfigurableApplicationContext applicationContext = ApplicationContextContext.getApplicationContext();
+ Map beansWithAnnotationMap = applicationContext.getBeansWithAnnotation(annoClazz);
+ Iterator var5 = beansWithAnnotationMap.entrySet().iterator();
+
+ while(var5.hasNext()) {
+ Map.Entry entry = (Map.Entry)var5.next();
+ Object object = entry.getValue();
+ Class clazz = object.getClass();
+ clazzSet.add(clazz);
+ }
+
+ return clazzSet;
+ }
+
+ public static Set resolve(String pkgPath, Class extends Annotation> annoClazz) {
+ Set paths = new HashSet();
+
+ try {
+ String pathPackage = getResourcePath(pkgPath);
+ Resource[] resources = resolver.getResources(pathPackage);
+
+ for(int i = 0; i < resources.length; ++i) {
+ Resource resource = resources[i];
+ MetadataReader metadataReader = register.getMetadataReader(resource);
+ AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
+ if (annotationMetadata.hasAnnotation(annoClazz.getName())) {
+ ClassMetadata classMetadata = metadataReader.getClassMetadata();
+ String className = classMetadata.getClassName();
+ ClassLoader classLoader = getClassLoader();
+ Class> clazz = classLoader.loadClass(className);
+ paths.add(clazz);
+ }
+ }
+
+ return paths;
+ } catch (Exception var13) {
+ throw new RuntimeException(var13);
+ }
+ }
+
+ public static Set resolveFromBeans(String pkgPath, Class extends Annotation> annoClazz) {
+ Set paths = new HashSet();
+ ConfigurableApplicationContext applicationContext = ApplicationContextContext.getApplicationContext();
+
+ try {
+ String pathPackage = getResourcePath(pkgPath);
+ Resource[] resources = resolver.getResources(pathPackage);
+
+ for(int i = 0; i < resources.length; ++i) {
+ Resource resource = resources[i];
+ MetadataReader metadataReader = register.getMetadataReader(resource);
+ AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
+ if (annotationMetadata.hasAnnotation(annoClazz.getName())) {
+ ClassMetadata classMetadata = metadataReader.getClassMetadata();
+ String className = classMetadata.getClassName();
+ ClassLoader classLoader = getClassLoader();
+ Class> clazz = classLoader.loadClass(className);
+
+ try {
+ Object bean = applicationContext.getBean(clazz);
+ if (bean == null) {
+ continue;
+ }
+ } catch (BeansException var15) {
+ continue;
+ }
+
+ paths.add(clazz);
+ }
+ }
+
+ return paths;
+ } catch (Exception var16) {
+ throw new RuntimeException(var16);
+ }
+ }
+
+ public static String getResourcePath(String packagePath) {
+ if (StringUtils.isEmpty(packagePath)) {
+ return "";
+ } else {
+ String resourcePath = "classpath*:" + ClassUtils.convertClassNameToResourcePath(environment.resolveRequiredPlaceholders(packagePath)) + "/**/*.class";
+ return resourcePath;
+ }
+ }
+
+ static ClassLoader getClassLoader() {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = ClassLoader.getSystemClassLoader();
+ }
+
+ return classLoader;
+ }
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/util/BeanUtils.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/util/BeanUtils.java
new file mode 100644
index 0000000..accccda
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/core/util/BeanUtils.java
@@ -0,0 +1,42 @@
+package cd.casic.module.process.core.util;
+
+import cd.casic.ci.commons.bean.exception.SystemException;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class BeanUtils {
+ public BeanUtils() {
+ }
+
+ public static PropertyDescriptor getPropertyDescriptor(Class clazz, String propertyName) {
+ try {
+ StringBuffer sb = new StringBuffer();
+ Field f = null;
+
+ try {
+ f = clazz.getDeclaredField(propertyName);
+ } catch (NoSuchFieldException var8) {
+ return null;
+ }
+
+ if (f == null) {
+ throw new SystemException("propertyName:" + propertyName + " not found.");
+ } else {
+ String var10000 = propertyName.substring(0, 1).toUpperCase();
+ String methodEnd = var10000 + propertyName.substring(1);
+ sb.append("set" + methodEnd);
+ Method setMethod = clazz.getDeclaredMethod(sb.toString(), f.getType());
+ sb.delete(0, sb.length());
+ sb.append("get" + methodEnd);
+ Method getMethod = clazz.getDeclaredMethod(sb.toString());
+ PropertyDescriptor pd = new PropertyDescriptor(propertyName, getMethod, setMethod);
+ return pd;
+ }
+ } catch (Exception var9) {
+ throw new SystemException("系统错误");
+// throw new SystemException(var9);
+ }
+ }
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/entity/PipelineFollowEntity.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/entity/PipelineFollowEntity.java
new file mode 100644
index 0000000..b395732
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/entity/PipelineFollowEntity.java
@@ -0,0 +1,20 @@
+package cd.casic.module.process.pipeline.definition.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+//@Table(name="pip_other_follow")
+@Data
+public class PipelineFollowEntity {
+// @Id
+// @GeneratorValue(length = 12)
+// @Column(name = "id")
+ @TableId
+ private String id;
+
+// @Column(name = "pipeline_id")
+ private String pipelineId;
+
+// @Column(name = "user_id")
+ private String userId ;
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/impl/PipelineFollowServiceImpl.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/impl/PipelineFollowServiceImpl.java
new file mode 100644
index 0000000..48b6a33
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/pipeline/definition/impl/PipelineFollowServiceImpl.java
@@ -0,0 +1,97 @@
+package cd.casic.module.process.pipeline.definition.impl;
+
+import cd.casic.ci.commons.bean.process.definition.Pipeline;
+import cd.casic.ci.commons.bean.process.definition.PipelineFollow;
+import cd.casic.ci.commons.bean.process.definition.PipelineFollowQuery;
+import cd.casic.ci.commons.bean.utils.PipelineUtil;
+import cd.casic.framework.commons.exception.ServiceException;
+import cd.casic.module.process.pipeline.definition.entity.PipelineFollowEntity;
+import cd.casic.module.process.process.definition.PipelineFollowService;
+import cd.casic.module.process.process.definition.dao.PipelineFollowDao;
+import cd.casic.module.process.toolkit.beans.BeanMapper;
+import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PipelineFollowServiceImpl implements PipelineFollowService {
+ @Resource
+ PipelineFollowDao pipelineFollowDao;
+
+ @Override
+ public void updateFollow(PipelineFollow pipelineFollow) {
+ Pipeline pipeline = pipelineFollow.getPipeline();
+ String pipelineId = pipeline.getId();
+ if (!PipelineUtil.isNoNull(pipelineId)){
+ throw new ServiceException(50001,"流水线id不能为空。");
+ }
+// TODO
+// String userId = LoginContext.getLoginId();
+ String userId = "";
+ List list =
+ pipelineFollowDao.findOneUserFollowPipeline(userId, pipelineId);
+ //用户为收藏该流水线
+ if (list.isEmpty()){
+ PipelineFollowEntity followEntity = BeanMapper.map(pipelineFollow, PipelineFollowEntity.class);
+ followEntity.setUserId(userId);
+ String follow = pipelineFollowDao.createFollow(followEntity);
+ if (!PipelineUtil.isNoNull(follow)){
+ throw new ServiceException(50001,"收藏失败");
+ }
+ //用户已收藏该流水线
+ }else {
+ deleteFollow(list.get(0).getId());
+ }
+ }
+
+ @Override
+ public List findUserFollowPipeline(String userId){
+ List list =
+ pipelineFollowDao.findUserFollowPipeline(userId);
+ return BeanMapper.mapList(list, PipelineFollow.class);
+ }
+
+ @Override
+ public List findFollowQueryList(PipelineFollowQuery followQuery){
+ List list =
+ pipelineFollowDao.findFollowQueryList(followQuery);
+ if (list == null || list.isEmpty()){
+ return Collections.emptyList();
+ }
+ return BeanMapper.mapList(list, PipelineFollow.class);
+ }
+
+ @Override
+ public void deleteFollow(String followId) {
+ pipelineFollowDao.deleteFollow(followId);
+ }
+
+
+ public void deletePipelineFollow(String pipelineId){
+ PipelineFollowQuery followQuery = new PipelineFollowQuery();
+ followQuery.setPipelineId(pipelineId);
+ List list = pipelineFollowDao.findFollowQueryList(followQuery);
+
+ for (PipelineFollowEntity pipelineFollowEntity : list) {
+ deleteFollow(pipelineFollowEntity.getId());
+ }
+
+ }
+
+ @Override
+ public PipelineFollow findOneFollow(String followId) {
+ return BeanMapper.map(pipelineFollowDao.findOneFollow(followId), PipelineFollow.class);
+ }
+
+ @Override
+ public List findAllFollow() {
+ return BeanMapper.mapList(pipelineFollowDao.findAllFollow(), PipelineFollow.class);
+ }
+
+ @Override
+ public List findAllFollowList(List idList) {
+ List followList = pipelineFollowDao.findAllFollowList(idList);
+ return BeanMapper.mapList(followList, PipelineFollow.class);
+ }
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/process/definition/dao/PipelineFollowDao.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/process/definition/dao/PipelineFollowDao.java
index 58b1299..aef549e 100644
--- a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/process/definition/dao/PipelineFollowDao.java
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/process/definition/dao/PipelineFollowDao.java
@@ -1,8 +1,14 @@
package cd.casic.module.process.process.definition.dao;
+import cd.casic.ci.commons.bean.process.definition.PipelineFollowQuery;
import cd.casic.framework.mybatis.core.mapper.BaseMapperX;
+import cd.casic.module.process.pipeline.definition.entity.PipelineFollowEntity;
import cd.casic.module.process.process.definition.dataobject.PipelineFollowDo;
import org.apache.ibatis.annotations.Mapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+
+import java.util.List;
/**
* @author by mianbin
@@ -12,4 +18,57 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface PipelineFollowDao extends BaseMapperX {
+
+ /**
+ * 创建收藏
+ * @param pipelineFollowEntity 收藏
+ * @return 收藏id
+ */
+ public String createFollow(PipelineFollowEntity pipelineFollowEntity);
+
+ /**
+ * 删除收藏
+ * @param followId 收藏id
+ */
+ public void deleteFollow(String followId);
+
+ /**
+ * 更新收藏
+ * @param pipelineFollowEntity 更新信息
+ */
+ public void updateFollow(PipelineFollowEntity pipelineFollowEntity);
+
+ /**
+ * 查询单个收藏信息
+ * @param followId 收藏id
+ * @return 收藏信息
+ */
+ public PipelineFollowEntity findOneFollow(String followId);
+
+ /**
+ * 查询所有收藏
+ * @return 收藏集合
+ */
+ public List findAllFollow();
+
+
+ public List findAllFollowList(List idList);
+
+ /**
+ * 查询用户是否收藏该流水线
+ * @param userId 用户id
+ * @param pipelineId 流水线id
+ * @return 收藏信息
+ */
+ public List findOneUserFollowPipeline(String userId, String pipelineId);
+
+ /**
+ * 查询用户是藏的流水线
+ * @param userId 用户id
+ * @return 收藏信息
+ */
+ public List findUserFollowPipeline(String userId);
+
+
+ public List findFollowQueryList(PipelineFollowQuery followQuery);
}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/BeanMapper.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/BeanMapper.java
new file mode 100644
index 0000000..cd3ecef
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/BeanMapper.java
@@ -0,0 +1,168 @@
+package cd.casic.module.process.toolkit.beans;
+
+import cd.casic.ci.commons.bean.exception.SystemException;
+import cd.casic.module.process.core.util.BeanUtils;
+import cd.casic.module.process.toolkit.beans.metadata.BeanMapperRegister;
+import cd.casic.module.process.toolkit.beans.model.BeanMapping;
+import cd.casic.module.process.toolkit.beans.model.FieldMapping;
+import ognl.Ognl;
+import ognl.OgnlException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class BeanMapper {
+ private static Logger logger = LoggerFactory.getLogger(BeanMapper.class);
+
+ public BeanMapper() {
+ }
+
+ public static T map(Object sourceObject, Class targetClz) {
+ if (sourceObject == null) {
+ return null;
+ } else if (targetClz == null) {
+ throw new SystemException("targetClass must not be null.");
+ } else {
+ try {
+ Class sourceClz = sourceObject.getClass();
+ BeanMapping beanMapping = BeanMapperRegister.getBeanMapping(sourceClz, targetClz);
+ if (beanMapping == null) {
+ throw new SystemException(String.format("bean mapper not found,source:%s,target:%s.", sourceClz.getName(), targetClz.getName()));
+ } else {
+ T targetObject = targetClz.newInstance();
+ List propertyMappingList = beanMapping.getPropertyMappingList();
+ Iterator var6 = propertyMappingList.iterator();
+
+ while(var6.hasNext()) {
+ FieldMapping propertyMapping = (FieldMapping)var6.next();
+ String source = propertyMapping.getSource();
+ String target = propertyMapping.getTarget();
+
+ try {
+ Object fieldValue;
+ if (isComplexField(source)) {
+ fieldValue = getParentFiled(sourceObject, source);
+ if (fieldValue == null) {
+ continue;
+ }
+ }
+
+ fieldValue = Ognl.getValue(source, sourceObject);
+ if (fieldValue != null) {
+ if (isComplexField(target)) {
+ initParentFieldIfNull(targetObject, target);
+ }
+
+ Ognl.setValue(target, targetObject, fieldValue);
+ }
+ } catch (OgnlException var11) {
+ throw new SystemException("表达式解析失败");
+ }
+ }
+
+ return targetObject;
+ }
+ } catch (InstantiationException var12) {
+// throw new SystemException(var12);
+ throw new SystemException("系统错误");
+ } catch (IllegalAccessException var13) {
+// throw new SystemException(var13);
+ throw new SystemException("系统错误");
+ }
+ }
+ }
+
+ static boolean isComplexField(String exp) {
+ return exp.contains(".");
+ }
+
+ static Object getParentFiled(Object sourceObject, String exp) {
+ String[] arr = exp.split("\\.");
+ String fieldName = arr[0];
+ PropertyDescriptor fieldPd = BeanUtils.getPropertyDescriptor(sourceObject.getClass(), fieldName);
+ Method fieldReadMethod = fieldPd.getReadMethod();
+ if (!Modifier.isPublic(fieldReadMethod.getDeclaringClass().getModifiers())) {
+ fieldReadMethod.setAccessible(true);
+ }
+
+ try {
+ Object fieldValue = fieldReadMethod.invoke(sourceObject);
+ return fieldValue;
+ } catch (IllegalAccessException var7) {
+// throw new SystemException(var7);
+ throw new SystemException("系统错误");
+ } catch (InvocationTargetException var8) {
+// throw new SystemException(var8);
+ throw new SystemException("系统错误");
+ }
+ }
+
+ static void initParentFieldIfNull(Object targetObject, String exp) {
+ if (exp.contains(".")) {
+ String[] arr = exp.split("\\.");
+ String fieldName = arr[0];
+
+ try {
+ PropertyDescriptor fieldPd = BeanUtils.getPropertyDescriptor(targetObject.getClass(), fieldName);
+ Method fieldReadMethod = fieldPd.getReadMethod();
+ if (!Modifier.isPublic(fieldReadMethod.getDeclaringClass().getModifiers())) {
+ fieldReadMethod.setAccessible(true);
+ }
+
+ Object fieldValue = fieldReadMethod.invoke(targetObject);
+ if (fieldValue == null) {
+ Class fieldType = fieldPd.getPropertyType();
+ fieldValue = fieldType.newInstance();
+ if (fieldValue == null) {
+ throw new SystemException(String.format("init field value error.", fieldName));
+ } else {
+ Method writeMethod = fieldPd.getWriteMethod();
+ if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
+ writeMethod.setAccessible(true);
+ }
+
+ writeMethod.invoke(targetObject, fieldValue);
+ }
+ }
+ } catch (IllegalAccessException var9) {
+// throw new SystemException(var9);
+ throw new SystemException("系统错误");
+ } catch (InvocationTargetException var10) {
+// throw new SystemException(var10);
+ throw new SystemException("系统错误");
+ } catch (InstantiationException var11) {
+// throw new SystemException(var11);
+ throw new SystemException("系统错误");
+ }
+ }
+ }
+
+ public static List mapList(List> sourceObjectList, Class targetClz) {
+ List targetList = new ArrayList();
+ if (sourceObjectList != null && sourceObjectList.size() != 0) {
+ try {
+ Iterator var3 = sourceObjectList.iterator();
+
+ while(var3.hasNext()) {
+ Object sourceObject = var3.next();
+ T targetObject = map(sourceObject, targetClz);
+ targetList.add(targetObject);
+ }
+
+ return targetList;
+ } catch (Exception var6) {
+// throw new SystemException(var6);
+ throw new SystemException("系统错误");
+ }
+ } else {
+ return targetList;
+ }
+ }
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapper.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapper.java
new file mode 100644
index 0000000..eb8ae3a
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapper.java
@@ -0,0 +1,18 @@
+package cd.casic.module.process.toolkit.beans.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Mapper {
+ Class source() default Object.class;
+
+ Class target() default Object.class;
+
+ String targetName() default "";
+
+ String targetAlias() default "";
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappers.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappers.java
new file mode 100644
index 0000000..fd62b1b
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappers.java
@@ -0,0 +1,12 @@
+package cd.casic.module.process.toolkit.beans.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Mappers {
+ Mapper[] value();
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapping.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapping.java
new file mode 100644
index 0000000..0e62e78
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mapping.java
@@ -0,0 +1,14 @@
+package cd.casic.module.process.toolkit.beans.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Mapping {
+ String source() default "";
+
+ String target() default "";
+}
\ No newline at end of file
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappings.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappings.java
new file mode 100644
index 0000000..5e7d8f2
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/annotation/Mappings.java
@@ -0,0 +1,12 @@
+package cd.casic.module.process.toolkit.beans.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Mappings {
+ Mapping[] value();
+}
\ No newline at end of file
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/metadata/BeanMapperRegister.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/metadata/BeanMapperRegister.java
new file mode 100644
index 0000000..f31ef2f
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/metadata/BeanMapperRegister.java
@@ -0,0 +1,267 @@
+package cd.casic.module.process.toolkit.beans.metadata;
+
+import cd.casic.ci.commons.bean.exception.SystemException;
+import cd.casic.module.process.core.resolver.AnnotationResourceResolver;
+import cd.casic.module.process.toolkit.beans.annotation.Mapper;
+import cd.casic.module.process.toolkit.beans.annotation.Mappers;
+import cd.casic.module.process.toolkit.beans.annotation.Mapping;
+import cd.casic.module.process.toolkit.beans.annotation.Mappings;
+import cd.casic.module.process.toolkit.beans.model.BeanMapping;
+import cd.casic.module.process.toolkit.beans.model.FieldMapping;
+import org.springframework.util.StringUtils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+public class BeanMapperRegister {
+ private static Map mappers = new HashMap();
+ private static final String RELA_SPLIT = "->";
+
+ public BeanMapperRegister() {
+ }
+
+ public void scan(String basePackage) {
+ Set classSet = AnnotationResourceResolver.resolve(basePackage, Mapper.class);
+ Iterator var3;
+ Class cls;
+ if (classSet != null && classSet.size() > 0) {
+ var3 = classSet.iterator();
+
+ while(var3.hasNext()) {
+ cls = (Class)var3.next();
+ Mapper mapper = (Mapper)cls.getAnnotation(Mapper.class);
+ this.parse(cls, mapper);
+ }
+ }
+
+ classSet = AnnotationResourceResolver.resolve(basePackage, Mappers.class);
+ if (classSet != null && classSet.size() > 0) {
+ var3 = classSet.iterator();
+
+ while(var3.hasNext()) {
+ cls = (Class)var3.next();
+ Mappers mappers = (Mappers)cls.getAnnotation(Mappers.class);
+ Mapper[] var6 = mappers.value();
+ int var7 = var6.length;
+
+ for(int var8 = 0; var8 < var7; ++var8) {
+ Mapper mapper = var6[var8];
+ this.parse(cls, mapper);
+ }
+ }
+ }
+
+ }
+
+ public BeanMapperRegister map(Class sourceClass, Class targetClass) {
+ BeanMapping mapperMeta = new BeanMapping();
+ mapperMeta.setSourceClass(sourceClass);
+ mapperMeta.setTargetClass(targetClass);
+ return this;
+ }
+
+ void parse(Class mapperClz, Mapper mapper) {
+ BeanMapping beanMapping = null;
+
+ try {
+ beanMapping = this.parseBeanMapping(mapperClz, mapper);
+ } catch (Exception var7) {
+ return;
+ }
+
+ mappers.put(getBeanMappingKey(beanMapping), beanMapping);
+ BeanMapping reverseBeanMapping = null;
+
+ try {
+ reverseBeanMapping = this.parseBeanMappingForReverse(beanMapping);
+ } catch (Exception var6) {
+ return;
+ }
+
+ mappers.put(getBeanMappingKey(reverseBeanMapping), reverseBeanMapping);
+ }
+
+ public BeanMapping parseBeanMappingForReverse(BeanMapping classMapping) {
+ BeanMapping reverseBeanMapping = new BeanMapping();
+ reverseBeanMapping.setSourceClass(classMapping.getTargetClass());
+ reverseBeanMapping.setTargetClass(classMapping.getSourceClass());
+ Iterator var3 = classMapping.getPropertyMappingList().iterator();
+
+ while(var3.hasNext()) {
+ FieldMapping item = (FieldMapping)var3.next();
+ FieldMapping propertyMapping = new FieldMapping();
+ propertyMapping.setSource(item.getTarget());
+ propertyMapping.setTarget(item.getSource());
+ reverseBeanMapping.getPropertyMappingList().add(propertyMapping);
+ }
+
+ return reverseBeanMapping;
+ }
+
+ BeanMapping parseBeanMapping(Class mapperClz, Mapper mapper) {
+ try {
+ BeanMapping beanMapping = new BeanMapping();
+ Class sourceClass = mapper.source();
+ if (sourceClass == Object.class) {
+ sourceClass = mapperClz;
+ }
+
+ Class targetClass = mapper.target();
+ if (targetClass == Object.class) {
+ String targetName = mapper.targetName();
+ if (!StringUtils.isEmpty(targetName)) {
+ targetClass = this.getClassByName(targetName);
+ } else {
+ targetClass = this.findTargetClassByRule(sourceClass);
+ }
+ }
+
+ beanMapping.setSourceClass(sourceClass);
+ beanMapping.setTargetClass(targetClass);
+ List propertyMappingList = this.parsePropertiesMapping(beanMapping);
+ beanMapping.setPropertyMappingList(propertyMappingList);
+ return beanMapping;
+ } catch (Exception var7) {
+ throw new SystemException(String.format("parse class:%s failed.", mapperClz.getName()));
+// throw new SystemException(String.format("parse class:%s failed.", mapperClz.getName()), var7);
+ }
+ }
+
+ public Class findTargetClassByRule(Class sourceClass) {
+ String className = sourceClass.getName();
+ String[] arr = className.split("\\.");
+ StringBuffer buffer = new StringBuffer();
+
+ for(int i = 0; i < arr.length; ++i) {
+ String item = arr[i];
+ if (i < arr.length - 2) {
+ buffer.append(item).append(".");
+ } else if (i == arr.length - 2) {
+ buffer.append("entity").append(".");
+ } else if (i == arr.length - 1) {
+ String entityName = item + "Entity";
+ buffer.append(entityName);
+ }
+ }
+
+ String targetName = buffer.toString();
+ Class targetClass = this.getClassByName(targetName);
+ return targetClass;
+ }
+
+ Class getClassByName(String className) {
+ try {
+ Class targetClass = Class.forName(className);
+ return targetClass;
+ } catch (ClassNotFoundException var6) {
+ try {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ Class> clazz = classLoader.loadClass(className);
+ return clazz;
+ } catch (ClassNotFoundException var5) {
+ throw new SystemException("class not found:" + className);
+// throw new SystemException("class not found:" + className, var6);
+ }
+ }
+ }
+
+ List parsePropertiesMapping(BeanMapping classMapping) {
+ List propertyMappingList = new ArrayList();
+ Class sourceClz = classMapping.getSourceClass();
+ Class targetClz = classMapping.getTargetClass();
+ Field[] fields = sourceClz.getDeclaredFields();
+ if (fields != null && fields.length > 0) {
+ }
+
+ Field[] var6 = fields;
+ int var7 = fields.length;
+
+ for(int var8 = 0; var8 < var7; ++var8) {
+ Field field = var6[var8];
+ if (field.getAnnotation(Mapping.class) != null) {
+ Mapping mapping = (Mapping)field.getAnnotation(Mapping.class);
+ this.validField(sourceClz, mapping.source());
+ this.validField(targetClz, mapping.target());
+ FieldMapping propertyMapping = buildPropertyMapping(field, mapping);
+ propertyMappingList.add(propertyMapping);
+ } else if (field.getAnnotation(Mappings.class) != null) {
+ Mappings mappings = (Mappings)field.getAnnotation(Mappings.class);
+ Mapping[] var11 = mappings.value();
+ int var12 = var11.length;
+
+ for(int var13 = 0; var13 < var12; ++var13) {
+ Mapping mapping = var11[var13];
+ this.validField(sourceClz, mapping.source());
+ this.validField(targetClz, mapping.target());
+ FieldMapping propertyMapping = buildPropertyMapping(field, mapping);
+ propertyMappingList.add(propertyMapping);
+ }
+ } else {
+ try {
+ this.validField(targetClz, field.getName());
+ } catch (Exception var16) {
+ continue;
+ }
+
+ FieldMapping propertyMapping = new FieldMapping(field.getName(), field.getName());
+ propertyMappingList.add(propertyMapping);
+ }
+ }
+
+ return propertyMappingList;
+ }
+
+ void validField(Class clz, String fieldName) {
+ if (!fieldName.contains(".")) {
+ try {
+ clz.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException var11) {
+ throw new SystemException(String.format("mapping field not found,clz:%s,field:%s", clz.getName(), fieldName));
+ }
+ } else {
+ String[] arr = fieldName.split("\\.");
+ String parentFieldName = arr[0];
+ Field parentField = null;
+
+ try {
+ parentField = clz.getDeclaredField(parentFieldName);
+ } catch (NoSuchFieldException var10) {
+ throw new SystemException(String.format("mapping field not found,clz:%s,field:%s", clz.getName(), parentFieldName));
+ }
+
+ String childFieldName = arr[1];
+ Class parentFieldClz = null;
+
+ try {
+ parentFieldClz = parentField.getType();
+ parentFieldClz.getDeclaredField(childFieldName);
+ } catch (NoSuchFieldException var9) {
+ throw new SystemException(String.format("mapping field not found,clz:%s,field:%s", parentFieldClz.getName(), childFieldName));
+ }
+ }
+
+ }
+
+ static FieldMapping buildPropertyMapping(Field field, Mapping mapping) {
+ FieldMapping propertyMappingMeta = new FieldMapping();
+ propertyMappingMeta.setSource(mapping.source());
+ propertyMappingMeta.setTarget(mapping.target());
+ return propertyMappingMeta;
+ }
+
+ public static BeanMapping getBeanMapping(Class sourceClass, Class targetClass) {
+ String mappingKey = getBeanMappingKey(sourceClass, targetClass);
+ BeanMapping classMapping = (BeanMapping)mappers.get(mappingKey);
+ return classMapping;
+ }
+
+ static String getBeanMappingKey(BeanMapping beanMapping) {
+ String var10000 = beanMapping.getSourceClass().getName();
+ return var10000 + "->" + beanMapping.getTargetClass().getName();
+ }
+
+ static String getBeanMappingKey(Class sourceClass, Class targetClass) {
+ String var10000 = sourceClass.getName();
+ return var10000 + "->" + targetClass.getName();
+ }
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/BeanMapping.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/BeanMapping.java
new file mode 100644
index 0000000..069c831
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/BeanMapping.java
@@ -0,0 +1,12 @@
+package cd.casic.module.process.toolkit.beans.model;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+@Data
+public class BeanMapping {
+ private Class sourceClass;
+ private Class targetClass;
+ private List propertyMappingList = new ArrayList();
+}
diff --git a/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/FieldMapping.java b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/FieldMapping.java
new file mode 100644
index 0000000..61e9f95
--- /dev/null
+++ b/modules/module-ci-process-biz/src/main/java/cd/casic/module/process/toolkit/beans/model/FieldMapping.java
@@ -0,0 +1,13 @@
+package cd.casic.module.process.toolkit.beans.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class FieldMapping {
+ private String source;
+ private String target;
+}