package com.vci.web.util;
|
|
import com.vci.starter.web.annotation.*;
|
import com.vci.starter.web.enumpck.BaseEnum;
|
import com.vci.starter.web.enumpck.BaseEnumInt;
|
import com.vci.starter.web.enumpck.VciFieldTypeEnum;
|
import com.vci.starter.web.exception.VciBaseException;
|
import com.vci.starter.web.util.ApplicationContextProvider;
|
import com.vci.starter.web.util.VciBaseUtil;
|
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
|
import com.vci.web.bo.BtmOrLinkProcessAttributeInfo;
|
import com.vci.web.constant.FieldConstant;
|
import com.vci.web.dto.*;
|
import com.vci.web.service.WebBtmIOServiceI;
|
import org.apache.commons.lang3.StringUtils;
|
import org.reflections.Reflections;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.CollectionUtils;
|
|
import java.lang.reflect.Field;
|
import java.math.BigDecimal;
|
import java.math.BigInteger;
|
import java.security.Timestamp;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 扫描注解工具--我们参考的是平台2021版本中的扫描工具,
|
* 将扫描包含了生命周期,枚举,业务类型,链接类型的对象。并保存到对象服务中
|
* @author weidy
|
* @date 2019/10/31 8:49 AM
|
*/
|
@Component
|
public class OsScanAnnotationTool {
|
|
|
/**
|
* 导入的服务
|
*/
|
@Autowired
|
private WebBtmIOServiceI btmIOService;
|
|
/**
|
* 日志
|
*/
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
|
/**
|
* 是否检查数据库表的参数名字
|
*/
|
public static final String CHECK_TABLE_EXIST = "check-table-exist";
|
|
|
/**
|
* 扫描对象注解后到对象服务中
|
* @param packageName 包名,如果为空则自动找VciPlatformScan注解里的内容,如果没有则抛出异常
|
* @throws VciBaseException 注解的内容或者参数有错误的时候抛出异常
|
*/
|
public void scanAnnotation2OSServer(String packageName) throws VciBaseException {
|
doScanAnnotation2OSServer(VciBaseUtil.str2List(packageName),null,null);
|
}
|
|
/**
|
* 扫描对象注解后到对象服务中
|
* @param packageName 包名,如果为空则自动找VciPlatformScan注解里的内容,如果没有则抛出异常
|
* @param entityNames 指定实体类名,必须全路径
|
* @throws VciBaseException 注解的内容或者参数有错误的时候抛出异常
|
*/
|
public void scanAnnotation2OSServer(String packageName, String entityNames) throws VciBaseException{
|
doScanAnnotation2OSServer(VciBaseUtil.str2List(packageName),VciBaseUtil.str2List(entityNames),null);
|
}
|
|
/**
|
* 扫描对象注解后到对象服务中
|
* @param packageName 包名,如果为空则自动找VciPlatformScan注解里的内容,如果没有则抛出异常
|
* @param entityNames 指定实体类名,必须全路径
|
* @param unScanEntityNames 不扫描的实体类名,必须是全路径
|
* @throws VciBaseException 注解的内容或者参数有错误的时候抛出异常
|
*/
|
public void scanAnnotation2OSServer(String packageName, String entityNames, String unScanEntityNames) throws VciBaseException{
|
doScanAnnotation2OSServer(VciBaseUtil.str2List(packageName),VciBaseUtil.str2List(entityNames),VciBaseUtil.str2List(unScanEntityNames));
|
}
|
|
/**
|
* 根据包名获取其中所有的对象
|
* @param lifeCycleClassList 生命周期类列表
|
* @param enumClassList 枚举类列表
|
* @param btmTypeClassList 业务类型类列表
|
* @param linkTypeClassList 链接类型类 列表
|
* @param packageNameList 包全路径,如果没有设置时自动获取VciPlatformScan注解
|
*/
|
private void scanClassForPackage(List<Class<?>> lifeCycleClassList, List<Class<?>> enumClassList, List<Class<?>> btmTypeClassList, List<Class<?>> linkTypeClassList, Collection<String> packageNameList){
|
//为了不重复造轮子,采用了org.reflections:reflections
|
if(CollectionUtils.isEmpty(packageNameList)){
|
List<String> tempPackageList = new ArrayList<String>();
|
//从spring里获取包含了VciPlatformScan的bean
|
Map<String, Object> withBeanMap = ApplicationContextProvider.getApplicationContext().getBeansWithAnnotation(VciPlatformScan.class);
|
if(!CollectionUtils.isEmpty(withBeanMap)){
|
for(String beanName : withBeanMap.keySet()){
|
Object bean = withBeanMap.get(beanName);
|
if(bean.getClass().isAnnotationPresent(VciPlatformScan.class)){
|
VciPlatformScan vciPlatformScan = bean.getClass().getAnnotation(VciPlatformScan.class);
|
String[] values = vciPlatformScan.value();
|
if(values !=null && values.length>0){
|
for(String p : values){
|
tempPackageList.add(p);
|
}
|
}
|
}
|
}
|
}
|
packageNameList = tempPackageList;
|
}
|
for(String packName:packageNameList){
|
Reflections reflections=new Reflections(packName);
|
//生命周期相关
|
Set<Class<?>> vciLifeCycleSet = reflections.getTypesAnnotatedWith(VciLifeCycle.class);
|
if(!CollectionUtils.isEmpty(vciLifeCycleSet)){
|
vciLifeCycleSet.stream().forEach(classObj->{
|
if(!classObj.isAnnotationPresent(Transient.class)){
|
lifeCycleClassList.add(classObj);
|
}
|
});
|
}
|
//枚举相关
|
Set<Class<?>> vciEnumSet = reflections.getTypesAnnotatedWith(VciEnum.class);
|
if(!CollectionUtils.isEmpty(vciEnumSet)){
|
vciEnumSet.stream().forEach(classObj->{
|
if(!classObj.isAnnotationPresent(Transient.class)){
|
enumClassList.add(classObj);
|
}
|
});
|
}
|
//业务类型相关
|
Set<Class<?>> vciBtmTypeSet = reflections.getTypesAnnotatedWith(VciBtmType.class);
|
if(!CollectionUtils.isEmpty(vciBtmTypeSet)){
|
//需要看看这些业务类型是否添加了@Transient注解,因为这种说明是平台的原本的业务类型
|
vciBtmTypeSet.stream().forEach(classObj ->{
|
if(!classObj.isAnnotationPresent(Transient.class)){
|
btmTypeClassList.add(classObj);
|
}
|
});
|
}
|
//链接类型相关
|
Set<Class<?>> vciLinkTypeSet = reflections.getTypesAnnotatedWith(VciLinkType.class);
|
if(!CollectionUtils.isEmpty(vciLinkTypeSet)){
|
vciLinkTypeSet.stream().forEach(classObj->{
|
if(!classObj.isAnnotationPresent(Transient.class)){
|
linkTypeClassList.add(classObj);
|
}
|
});
|
}
|
}
|
}
|
|
/**
|
* 根据实体类的名称获取对应的class。注意实体类名称必须是全路径
|
* @param lifeCycleClassList 生命周期类列表
|
* @param enumClassList 枚举类列表
|
* @param btmTypeClassList 业务类型类列表
|
* @param linkTypeClassList 链接类型类 列表
|
* @param entityNameList 实体类全路径
|
*/
|
private void scanClassForEntity(List<Class<?>> lifeCycleClassList, List<Class<?>> enumClassList, List<Class<?>> btmTypeClassList, List<Class<?>> linkTypeClassList, Collection<String> entityNameList) throws VciBaseException{
|
if(!CollectionUtils.isEmpty(entityNameList)){
|
for(String entityName:entityNameList){
|
try {
|
Class entityClass = Class.forName(entityName);
|
if(entityClass.isAnnotationPresent(VciBtmType.class) && !entityClass.isAnnotationPresent(Transient.class)){
|
btmTypeClassList.add(entityClass);
|
}
|
if(entityClass.isAnnotationPresent(VciLifeCycle.class)){
|
lifeCycleClassList.add(entityClass);
|
}
|
if(entityClass.isAnnotationPresent(VciEnum.class)){
|
enumClassList.add(entityClass);
|
}
|
if(entityClass.isAnnotationPresent(VciLinkType.class)){
|
linkTypeClassList.add(entityClass);
|
}
|
} catch (ClassNotFoundException e) {
|
if(logger.isErrorEnabled()){
|
logger.error("扫描业务类型相关内容出现了错误",e);
|
}
|
throw new VciBaseException("扫描业务类型相关内容的时候发现实体类{0}不存在",new String[]{entityName},e);
|
}
|
}
|
}
|
}
|
|
/**
|
* 执行扫描业务类型相关内容
|
* @param packageNameCollection 包名集合
|
* @param entityCollection 实体类集合
|
* @throws VciBaseException 扫描类不存在,或者注解不规范都会出现异常
|
*/
|
public void doScanAnnotation2OSServer(Collection<String> packageNameCollection, Collection<String> entityCollection) throws VciBaseException {
|
doScanAnnotation2OSServer(packageNameCollection,entityCollection,null);
|
}
|
|
/**
|
* 执行扫描业务类型相关内容
|
* @param packageNameCollection 包名集合
|
* @param entityCollection 实体类集合
|
* @param unScanEntityCollection 不扫描的实体类集合
|
* @throws VciBaseException 扫描类不存在,或者注解不规范都会出现异常
|
*/
|
public void doScanAnnotation2OSServer(Collection<String> packageNameCollection, Collection<String> entityCollection, Collection<String> unScanEntityCollection) throws VciBaseException{
|
logger.info("执行扫描平台中的相关对象");
|
Map<String, OsStatusDTO> statusDTOMap = new HashMap<String, OsStatusDTO>();
|
Map<String, OsLifeCycleDTO> lifeCycleDTOMap = new HashMap<String, OsLifeCycleDTO>();
|
Map<String, OsEnumDTO> enumDTOMap = new HashMap<String, OsEnumDTO>();
|
Map<String, OsAttributeDTO> attributeDTOMap = new HashMap<String, OsAttributeDTO>();
|
Map<String,OsBtmTypeDTO> btmTypeDTOMap = new HashMap<String,OsBtmTypeDTO>();
|
Map<String,OsLinkTypeDTO> linkTypeDTOMap = new HashMap<String,OsLinkTypeDTO>();
|
|
List<Class<?>> lifeCycleClassList = new ArrayList<Class<?>>();
|
List<Class<?>> enumClassList = new ArrayList<Class<?>>();
|
List<Class<?>> btmTypeClassList = new ArrayList<Class<?>>();
|
List<Class<?>> linkTypeClassList = new ArrayList<Class<?>>();
|
//先看包下面
|
scanClassForPackage(lifeCycleClassList,enumClassList,btmTypeClassList,linkTypeClassList,packageNameCollection);
|
//再看指定的,比如文件不是当前项目下的
|
scanClassForEntity(lifeCycleClassList,enumClassList,btmTypeClassList,linkTypeClassList,entityCollection);
|
|
if(!CollectionUtils.isEmpty(unScanEntityCollection)){
|
lifeCycleClassList = removeUnScanClass(lifeCycleClassList,unScanEntityCollection);
|
enumClassList = removeUnScanClass(enumClassList,unScanEntityCollection);
|
btmTypeClassList = removeUnScanClass(btmTypeClassList,unScanEntityCollection);
|
linkTypeClassList = removeUnScanClass(linkTypeClassList,unScanEntityCollection);
|
}
|
|
if(!CollectionUtils.isEmpty(lifeCycleClassList)){
|
List<Class<?>> scanedClassList = new ArrayList<Class<?>>();
|
for(int i = 0 ; i < lifeCycleClassList.size(); i ++){
|
Class<?> lifeClass = lifeCycleClassList.get(i);
|
if(!scanedClassList.contains(lifeClass)){
|
scanStatusAndLifeCycle(lifeClass,statusDTOMap,lifeCycleDTOMap);
|
scanedClassList.add(lifeClass);
|
}
|
}
|
}
|
|
if(!CollectionUtils.isEmpty(enumClassList)){
|
List<Class<?>> scanedClassList = new ArrayList<Class<?>>();
|
for(int i = 0 ; i < enumClassList.size(); i ++){
|
Class<?> enumClass = enumClassList.get(i);
|
if(!scanedClassList.contains(enumClass)){
|
scanEnum(enumClass,enumDTOMap);
|
scanedClassList.add(enumClass);
|
}
|
}
|
}
|
|
if(!CollectionUtils.isEmpty(btmTypeClassList)){
|
List<Class<?>> scanedClassList = new ArrayList<Class<?>>();
|
for(int i = 0 ; i < btmTypeClassList.size(); i ++){
|
Class<?> btmTypeClass = btmTypeClassList.get(i);
|
if(!scanedClassList.contains(btmTypeClass)){
|
scanAttributeAndBtmType(btmTypeClass,attributeDTOMap,btmTypeDTOMap);
|
scanedClassList.add(btmTypeClass);
|
}
|
}
|
}
|
|
if(!CollectionUtils.isEmpty(linkTypeClassList)){
|
List<Class<?>> scanedClassList = new ArrayList<Class<?>>();
|
for(int i = 0 ; i < linkTypeClassList.size(); i ++){
|
Class<?> linkTypeClass = linkTypeClassList.get(i);
|
if(!scanedClassList.contains(linkTypeClass)){
|
scanAttributeAndLinkType(linkTypeClass,attributeDTOMap,linkTypeDTOMap);
|
scanedClassList.add(linkTypeClass);
|
}
|
}
|
}
|
|
//ok.准备传递数据
|
|
OsBtmTypeExportDTO btmTypeExportDTO = new OsBtmTypeExportDTO();
|
//属性的数据传输对象
|
btmTypeExportDTO.setAttributeDTOList(attributeDTOMap.values());
|
//生命周期的数据传输对象
|
btmTypeExportDTO.setLifeCycleDTOList(lifeCycleDTOMap.values());
|
//状态
|
btmTypeExportDTO.setStatusDTOList(statusDTOMap.values());
|
//枚举
|
btmTypeExportDTO.setEnumDTOList(enumDTOMap.values());
|
//业务类型
|
btmTypeExportDTO.setBtmTypeDTOList(btmTypeDTOMap.values());
|
//链接类型
|
btmTypeExportDTO.setLinkTypeDTOList(linkTypeDTOMap.values());
|
//执行导入的
|
btmIOService.importBtmTypes(btmTypeExportDTO);
|
}
|
|
/**
|
* 去除重复的类
|
* @param beanList 类列表
|
* @param unScanEntityCollection 不扫描的类名
|
*/
|
private List<Class<?>> removeUnScanClass(Collection<Class<?>> beanList,Collection<String> unScanEntityCollection){
|
List<Class<?>> needScanClassList = new ArrayList<Class<?>>();
|
if(!CollectionUtils.isEmpty(beanList)) {
|
for(Class<?> cl:beanList){
|
if(!unScanEntityCollection.contains(cl.getName())){
|
needScanClassList.add(cl);
|
}
|
}
|
}
|
return needScanClassList;
|
}
|
|
/**
|
* 扫描链接类型的对象
|
* @param linkTypeClass 链接类型类的对象
|
* @param attributeDTOMap 属性的映射
|
* @param linkTypeDTOMap 链接类型的映射
|
*/
|
private void scanAttributeAndLinkType(Class<?> linkTypeClass, Map<String,OsAttributeDTO> attributeDTOMap, Map<String,OsLinkTypeDTO> linkTypeDTOMap) {
|
String className = linkTypeClass.getName();
|
logger.info("链接类型的类==" + className);
|
OsLinkTypeDTO linkTypeDTO = new OsLinkTypeDTO();
|
if(linkTypeClass.isAnnotationPresent(VciLinkType.class)){
|
VciLinkType linkType = linkTypeClass.getAnnotation(VciLinkType.class);
|
linkTypeDTO.setId(linkType.name());
|
linkTypeDTO.setName(linkType.text());
|
linkTypeDTO.setFromBtmType(arrays2String(linkType.fromBtmTypes()));
|
linkTypeDTO.setToBtmType(arrays2String(linkType.toBtmTypes()));
|
}else{
|
throw new VciBaseException("链接类型类必须要添加VciLinkType",
|
new Object[]{className});
|
}
|
if(StringUtils.isBlank(linkTypeDTO.getId())){
|
linkTypeDTO.setId(VciBaseUtil.toLowForFirst(linkTypeClass.getSimpleName()));
|
if(linkTypeDTO.getId().endsWith("DO")){
|
linkTypeDTO.setId(linkTypeDTO.getId().substring(0,linkTypeDTO.getId().length()-2));
|
}
|
}
|
|
//找是否已经存在
|
if(linkTypeDTOMap.containsKey(linkTypeDTO.getId().toLowerCase())){
|
throw new VciBaseException("链接类型{0}[{1}]在系统中已经存在,请不要重复添加;与之相同名称的链接类型类路径为{2}",
|
new Object[]{linkTypeDTO.getId(),linkTypeDTO.getName(),linkTypeDTOMap.get(linkTypeDTO.getId().toLowerCase().trim()).getClassFullName()});
|
}
|
|
//找属性
|
List<Field> fields = new ArrayList<Field>();
|
Collections.addAll(fields,linkTypeClass.getDeclaredFields());
|
List<OsBtmTypeLinkAttributesDTO> linkTypeAttributeVOList = new ArrayList<OsBtmTypeLinkAttributesDTO>();
|
BtmOrLinkProcessAttributeInfo processAttributeInfo = new BtmOrLinkProcessAttributeInfo();
|
processAttributeInfo.setId(linkTypeClass.getName());
|
processAttributeInfo.setName(linkTypeDTO.getName());
|
processAttributeInfo.setLinkType(true);
|
scanAttributes(fields,attributeDTOMap,linkTypeAttributeVOList,processAttributeInfo);
|
linkTypeDTO.setAttributesDTOList(linkTypeAttributeVOList);
|
linkTypeDTOMap.put(linkTypeDTO.getId().toLowerCase().trim(),linkTypeDTO);
|
}
|
|
/**
|
* 数组转换为逗号分隔的字符串
|
* @param arrays 数组
|
* @return 逗号分隔的字符串
|
*/
|
private String arrays2String(String[] arrays){
|
return VciBaseUtil.array2String(arrays);
|
}
|
|
/**
|
* 序列化的属性名称
|
*/
|
private static final String SERIALVERSION_FIELD_NAME = "serialVersionUID";
|
|
/**
|
* 扫描属性
|
* @param fields 属性字段数组
|
* @param attributeDTOMap 属性的传输映射
|
* @param useAttributeVOList 使用的属性
|
* @param processAttributeInfo 业务类型或者链接类型
|
*/
|
private void scanAttributes(List<Field> fields, Map<String,OsAttributeDTO> attributeDTOMap, List<OsBtmTypeLinkAttributesDTO> useAttributeVOList, BtmOrLinkProcessAttributeInfo processAttributeInfo){
|
for(Field field: fields){
|
field.setAccessible(true);
|
OsAttributeDTO attributeDTO = new OsAttributeDTO();
|
scanField2Attribute(field,attributeDTO,attributeDTOMap,processAttributeInfo);
|
if(StringUtils.isNotBlank(attributeDTO.getAttributeDataType())) {
|
OsBtmTypeLinkAttributesDTO linkAttributesDTO = new OsBtmTypeLinkAttributesDTO();
|
copyAttribute2BtmTypeLink(linkAttributesDTO, attributeDTO);
|
useAttributeVOList.add(linkAttributesDTO);
|
}
|
}
|
}
|
|
/**
|
* 扫描属性和业务类型
|
* @param btmTypeClass 业务类型的类
|
* @param attributeDTOMap 属性的数据传输对象映射,key是属性的英文名称小写
|
* @param btmTypeDTOMap 业务类型的数据传输对象映射,key是业务类型的英文名称小写
|
*/
|
private void scanAttributeAndBtmType(Class<?> btmTypeClass, Map<String,OsAttributeDTO> attributeDTOMap, Map<String,OsBtmTypeDTO> btmTypeDTOMap) {
|
String className = btmTypeClass.getName();
|
logger.info("业务类型的类==" + className);
|
OsBtmTypeDTO btmTypeDTO = new OsBtmTypeDTO();
|
if(btmTypeClass.isAnnotationPresent(VciBtmType.class)){
|
VciBtmType vciBtmType = btmTypeClass.getAnnotation(VciBtmType.class);
|
btmTypeDTO.setId(vciBtmType.name());
|
btmTypeDTO.setName(vciBtmType.text());
|
// btmTypeDTO.setTableName(StringUtils.isBlank(vciBtmType.tableName())?VciBaseUtil.getTableName(btmTypeDTO.getName()):vciBtmType.tableName());
|
//btmTypeDTO.setSecretFlag(vciBtmType.secretAble());
|
btmTypeDTO.setDescription(vciBtmType.description());
|
btmTypeDTO.setLifeCycleId(vciBtmType.lifeCycle());
|
String[] subLifeCycles = vciBtmType.subLifeCycle();
|
if(subLifeCycles!=null&& subLifeCycles.length > 0){
|
btmTypeDTO.setSubLifeCycleId(arrays2String(subLifeCycles));
|
}
|
btmTypeDTO.setInputRevisionFlag(vciBtmType.revisionRuleInput());
|
btmTypeDTO.setRevisionRuleId(vciBtmType.revisionRule());
|
btmTypeDTO.setVersionRule(vciBtmType.versionRule().getValue());
|
}else{
|
btmTypeDTO.setSecretFlag(false);
|
btmTypeDTO.setLifeCycleId("");
|
btmTypeDTO.setInputRevisionFlag(false);
|
}
|
if(StringUtils.isBlank(btmTypeDTO.getId())){
|
btmTypeDTO.setId(VciBaseUtil.toLowForFirst(btmTypeClass.getSimpleName()));
|
if(btmTypeDTO.getId().endsWith("DO")){
|
btmTypeDTO.setId(btmTypeDTO.getId().substring(0,btmTypeDTO.getId().length()-2));
|
}
|
}
|
if(btmTypeDTO.getId().length()>18){
|
throw new VciBaseException("业务类型[{0}]名称的长度不能超过18位,当前为{1}",new String[]{btmTypeDTO.getName(),btmTypeDTO.getId()});
|
}
|
if(StringUtils.isBlank(btmTypeDTO.getLifeCycleId())){
|
btmTypeDTO.setLifeCycleFlag(false);
|
}else{
|
btmTypeDTO.setLifeCycleFlag(true);
|
}
|
|
btmTypeDTO.setClassFullName(className);
|
btmTypeDTO.setImplClass(className);
|
if(StringUtils.isNotBlank(btmTypeDTO.getRevisionRuleId()) || btmTypeDTO.isInputRevisionFlag()){
|
btmTypeDTO.setRevisionFlag(true);
|
}else{
|
btmTypeDTO.setRevisionFlag(false);
|
}
|
//从注释里获取名称
|
|
//找是否已经存在
|
if(btmTypeDTOMap.containsKey(btmTypeDTO.getId().toLowerCase())){
|
throw new VciBaseException("业务类型{0}[{1}]在系统中已经存在,请不要重复添加;与之相同名称的业务类型类路径为{2}",
|
new Object[]{btmTypeDTO.getId(),btmTypeDTO.getName(),btmTypeDTOMap.get(btmTypeDTO.getId().toLowerCase().trim()).getClassFullName()});
|
}
|
|
BtmOrLinkProcessAttributeInfo processAttributeInfo = new BtmOrLinkProcessAttributeInfo();
|
processAttributeInfo.setId(className);
|
processAttributeInfo.setName(btmTypeDTO.getName());
|
processAttributeInfo.setSecret(btmTypeDTO.isSecretFlag());
|
processAttributeInfo.setRevision(btmTypeDTO.isRevisionFlag());
|
processAttributeInfo.setLinkType(false);
|
processAttributeInfo.setLifeCycle(btmTypeDTO.isLifeCycleFlag());
|
|
//处理属性
|
List<Field> fields =new ArrayList<Field>();
|
Collections.addAll(fields,btmTypeClass.getDeclaredFields());
|
List<OsBtmTypeLinkAttributesDTO> btmTypeLinkAttributesDTOList = new ArrayList<OsBtmTypeLinkAttributesDTO>();
|
scanAttributes(fields,attributeDTOMap,btmTypeLinkAttributesDTOList,processAttributeInfo);
|
btmTypeDTO.setAttributesDTOList(btmTypeLinkAttributesDTOList);
|
btmTypeDTOMap.put(btmTypeDTO.getId().toLowerCase().trim(),btmTypeDTO);
|
}
|
|
/**
|
* 从类的属性字段上获取注解并拷贝到属性对象中
|
* @param field 属性字段
|
* @param attributeDTO 属性对象
|
* @param attributeDTOMap 属性的映射,key是属性的英文名称大写
|
* @param processAttributeInfo 业务类型或者链接类型的基本信息
|
*/
|
private void scanField2Attribute(Field field, OsAttributeDTO attributeDTO, Map<String,OsAttributeDTO> attributeDTOMap, BtmOrLinkProcessAttributeInfo processAttributeInfo){
|
//找基本的信息
|
if(field.isAnnotationPresent(Transient.class) || "serialversionuid".equalsIgnoreCase(field.getName())){
|
//加了这个注解的属性也是不持久化的
|
return;
|
}
|
if(field.isAnnotationPresent(Column.class)){
|
Column column = field.getAnnotation(Column.class);
|
attributeDTO.setId(column.name());
|
if(StringUtils.isBlank(attributeDTO.getId())){
|
attributeDTO.setId(field.getName());
|
}
|
attributeDTO.setName(column.columnDefinition());
|
attributeDTO.setNullableFlag(column.nullable());
|
attributeDTO.setDefaultValue(column.defaultValue());
|
attributeDTO.setEnumId(column.useEnum());
|
attributeDTO.setBtmTypeId(column.useRefer());
|
attributeDTO.setAttrLength(column.length());
|
attributeDTO.setPrecisionLength(column.precision());
|
attributeDTO.setScaleLength(column.scale());
|
String[] ranges = column.range();
|
if(ranges!=null&& ranges.length > 0){
|
attributeDTO.setRange(VciBaseUtil.array2String(ranges));
|
}
|
}else{
|
attributeDTO.setNullableFlag(true);
|
attributeDTO.setId(field.getName());
|
}
|
String attrLowId = attributeDTO.getId().toLowerCase(Locale.ROOT);
|
if(FieldConstant.REVISION_MANAGE_FIELD_MAP.containsKey(attrLowId)
|
||FieldConstant.BASIC_FIELD_MAP.containsKey(attrLowId)
|
||FieldConstant.BASE_MODEL_COMPATIBILITY_MAP.containsKey(attrLowId)
|
||FieldConstant.LIFECYCLE_MANAGE_FIELD_MAP.containsKey(attrLowId)
|
||FieldConstant.LINK_TYPE_FIELD_MAP.containsKey(attrLowId)){
|
//基础的属性
|
return;
|
}
|
if(StringUtils.isBlank(attributeDTO.getId())){
|
attributeDTO.setId(field.getName());
|
}
|
if(StringUtils.isBlank(attributeDTO.getName())){
|
attributeDTO.setName(attributeDTO.getId());
|
}
|
String attributeLowerId = attributeDTO.getId().toLowerCase();
|
//找类型配置的信息
|
Class<?> fieldType = field.getType();
|
if (field.isAnnotationPresent(VciFieldType.class)) {
|
VciFieldType vciFieldType = field.getAnnotation(VciFieldType.class);
|
VciFieldTypeEnum fieldTypeEnum = vciFieldType.value();
|
if(fieldTypeEnum == null){
|
attributeDTO.setAttributeDataType(VciFieldTypeEnum.VTString.name());
|
}else {
|
if (fieldTypeEnum.equals(VciFieldTypeEnum.VTBoolean)) {
|
attributeDTO.setAttrLength(5);
|
}
|
if (fieldTypeEnum.equals(VciFieldTypeEnum.VTFilePath)) {
|
attributeDTO.setAttrLength(50);
|
}
|
attributeDTO.setAttributeDataType(fieldTypeEnum.name());
|
}
|
} else {
|
if (fieldType.equals(Integer.class) || fieldType.equals(int.class)
|
|| fieldType.equals(Short.class)
|
|| fieldType.equals(short.class)) {
|
attributeDTO.setAttributeDataType(VciFieldTypeEnum.VTInteger.name());
|
} else if (fieldType.equals(Long.class) || fieldType.equals(long.class)) {
|
attributeDTO.setAttributeDataType(VciFieldTypeEnum.VTLong.name());
|
} else if (fieldType.equals(Double.class) || fieldType.equals(double.class)
|
|| fieldType.equals(Float.class) || fieldType.equals(float.class)
|
|| fieldType.equals(BigDecimal.class) || fieldType.equals(BigInteger.class)) {
|
attributeDTO.setAttributeDataType(VciFieldTypeEnum.VTDouble.name());
|
} else if (fieldType.equals(Date.class) || fieldType.equals(Timestamp.class)) {
|
attributeDTO.setAttributeDataType(VciFieldTypeEnum.VTDateTime.name());
|
} else {
|
attributeDTO.setAttributeDataType(VciFieldTypeEnum.VTString.name());
|
}
|
}
|
if (attributeDTO.getAttrLength() == null) {
|
attributeDTO.setAttrLength(0);
|
}
|
if (attributeDTO.getAttrLength() == 0 &&
|
(VciFieldTypeEnum.VTDouble.name().equals(attributeDTO.getAttributeDataType()) || fieldType.equals(Double.class) || fieldType.equals(double.class)
|
|| fieldType.equals(Float.class) || fieldType.equals(float.class)
|
|| fieldType.equals(BigDecimal.class) || fieldType.equals(BigInteger.class))) {
|
attributeDTO.setAttrLength(8);
|
}
|
if (StringUtils.isBlank(attributeDTO.getBtmTypeId())
|
&& field.isAnnotationPresent(VciUseRefer.class)) {
|
VciUseRefer refer = field.getAnnotation(VciUseRefer.class);
|
attributeDTO.setBtmTypeId(refer.value());
|
}
|
if (StringUtils.isBlank(attributeDTO.getEnumId())
|
&& field.isAnnotationPresent(VciUseEnum.class)) {
|
VciUseEnum useEnum = field.getAnnotation(VciUseEnum.class);
|
attributeDTO.setEnumId(useEnum.value());
|
}
|
if (attributeDTO.getAttrLength() == 0 &&
|
VciFieldTypeEnum.VTString.name().equals(attributeDTO.getAttributeDataType())){
|
if(StringUtils.isNotBlank(attributeDTO.getBtmTypeId())
|
|| StringUtils.isNotBlank(attributeDTO.getEnumId())){
|
attributeDTO.setAttrLength(50);
|
}else {
|
attributeDTO.setAttrLength(150);
|
}
|
}
|
if (attributeDTOMap.containsKey(attributeLowerId)) {
|
OsAttributeDTO existAttributeDTO = attributeDTOMap.get(attributeLowerId);
|
if (existAttributeDTO.getAttrLength() < attributeDTO.getAttrLength()) {
|
existAttributeDTO.setAttrLength(attributeDTO.getAttrLength());
|
}
|
} else {
|
attributeDTOMap.put(attributeDTO.getId().trim().toLowerCase(), attributeDTO);
|
}
|
}
|
|
|
/**
|
* 拷贝属性的内容到业务类型关联属性
|
* @param linkAttributesDTO 业务类型关联属性的对象
|
* @param attributeDTO 属性对象
|
*/
|
private void copyAttribute2BtmTypeLink(OsBtmTypeLinkAttributesDTO linkAttributesDTO,OsAttributeDTO attributeDTO){
|
linkAttributesDTO.setName(attributeDTO.getName());
|
linkAttributesDTO.setAttrDataType(attributeDTO.getAttributeDataType());
|
linkAttributesDTO.setId(attributeDTO.getId());
|
linkAttributesDTO.setAttributeLength(attributeDTO.getAttrLength());
|
linkAttributesDTO.setDefaultValue(attributeDTO.getDefaultValue());
|
linkAttributesDTO.setNullableFlag(attributeDTO.isNullableFlag());
|
linkAttributesDTO.setPrecisionLength(attributeDTO.getPrecisionLength());
|
linkAttributesDTO.setEnumId(attributeDTO.getEnumId());
|
linkAttributesDTO.setReferBtmTypeId(attributeDTO.getBtmTypeId());
|
linkAttributesDTO.setDescription(attributeDTO.getDescription());
|
}
|
|
/**
|
* 扫描枚举
|
* @param enumClass 枚举类
|
* @param enumDTOMap 枚举的映射,key是枚举的英文名称小写,value是枚举的显示对象
|
*/
|
private void scanEnum(Class<?> enumClass, Map<String,OsEnumDTO> enumDTOMap) {
|
String className = enumClass.getName();
|
logger.info("枚举的类==" + className);
|
if(!enumClass.isEnum()){
|
throw new VciBaseException("类{0}不是枚举类",
|
new Object[]{className});
|
}
|
Object[] enumObjs = enumClass.getEnumConstants();
|
OsEnumDTO enumDTO = new OsEnumDTO();
|
if(enumClass.isAnnotationPresent(VciEnum.class)){
|
VciEnum vciEnum = enumClass.getAnnotation(VciEnum.class);
|
enumDTO.setId(vciEnum.name());
|
enumDTO.setName(vciEnum.text());
|
enumDTO.setLength(50);
|
enumDTO.setDescription(vciEnum.description());
|
}
|
//如果没有添加VciEnum注解,则取类的名称小写
|
if(StringUtils.isBlank(enumDTO.getId())){
|
enumDTO.setId(VciBaseUtil.toLowForFirst(enumClass.getSimpleName()));
|
}
|
if(StringUtils.isBlank(enumDTO.getName())){
|
enumDTO.setName(enumDTO.getId());
|
}
|
if(enumDTOMap.containsKey(enumDTO.getId().trim().toLowerCase())){
|
throw new VciBaseException("枚举{0}[{1}]在系统中已经存在,请不要重复添加;与之相同名称的枚举类路径为{2}",
|
new Object[]{enumDTO.getId(),enumDTO.getName(),enumDTOMap.get(enumDTO.getId().toLowerCase().trim()).getClassFullName()});
|
}
|
|
Map<String,String> itemMap = new HashMap<String,String>();
|
for(Object obj : enumObjs){
|
Class<?>[] objInterfaces = obj.getClass().getInterfaces();
|
if(VciBaseUtil.inArray(objInterfaces, BaseEnum.class)){
|
BaseEnum baseEnum = (BaseEnum)obj;
|
enumDTO.setEnumValueDataType("string");
|
itemMap.put(baseEnum.getValue(),baseEnum.getText());
|
}else if(VciBaseUtil.inArray(objInterfaces, BaseEnumInt.class)){
|
BaseEnumInt baseEnum = (BaseEnumInt)obj;
|
enumDTO.setEnumValueDataType("int");
|
itemMap.put(baseEnum.getValue() + "",baseEnum.getText());
|
}else{
|
throw new VciBaseException("枚举所属的类{0}没有实现BaseEnum或者BaseEnumInt的接口,请开发人员改正",new Object[]{className});
|
}
|
}
|
enumDTO.setClassFullName(className);
|
enumDTO.setItemMaps(itemMap);
|
enumDTOMap.put(enumDTO.getId().trim().toLowerCase(),enumDTO);
|
}
|
|
/**
|
* 扫描状态和生命周期
|
* @param lifeCycleClass 生命周期的类
|
* @param statusDTOMap 状态的传输对象映射
|
* @param lifeCycleDTOMap 生命周期的对象映射
|
* @throws VciBaseException 注解的内容有错误的时候会抛出异常
|
*/
|
private void scanStatusAndLifeCycle(Class<?> lifeCycleClass, Map<String, OsStatusDTO> statusDTOMap, Map<String, OsLifeCycleDTO> lifeCycleDTOMap) throws VciBaseException{
|
logger.info("生命周期的类==" + lifeCycleClass.getName());
|
if(!lifeCycleClass.isEnum()){
|
throw new VciBaseException("@VciLifeCycle这个注解只能使用在枚举类上,{0}",new Object[]{lifeCycleClass.getSimpleName()});
|
}
|
if(lifeCycleClass.isAnnotationPresent(VciLifeCycle.class)){
|
VciLifeCycle vciLifeCycle = lifeCycleClass.getAnnotation(VciLifeCycle.class);
|
String id = vciLifeCycle.name();
|
if(StringUtils.isBlank(id)){
|
//可能注解没有写值
|
id=VciBaseUtil.toLowForFirst(lifeCycleClass.getSimpleName());
|
}
|
String name = vciLifeCycle.text();
|
if(StringUtils.isBlank(name)){
|
name = id;
|
}
|
if(lifeCycleDTOMap.containsKey(id.toLowerCase().trim())){
|
throw new VciBaseException("生命周期{0}[{1}]在系统中已经存在,请不要重复添加;与之相同的生命周期的类路径为{2}",new Object[]{id,name,lifeCycleDTOMap.get(id.toLowerCase().trim()).getClassFullName()});
|
}
|
String className = lifeCycleClass.getName();
|
OsLifeCycleDTO lifeCycleDTO = new OsLifeCycleDTO();
|
lifeCycleDTO.setId(id);
|
lifeCycleDTO.setName(name);
|
lifeCycleDTO.setStartStatus(vciLifeCycle.startStatus());
|
//找里面所有的状态
|
Object[] enumObjs = lifeCycleClass.getEnumConstants();
|
Map<String,String> statusMapInThisLifeCycle = new HashMap<String,String>();
|
for(int i = 0 ; i < enumObjs.length; i ++ ){
|
Object obj =enumObjs[i];
|
Class<?>[] objInterfaces = obj.getClass().getInterfaces();
|
if(VciBaseUtil.inArray(objInterfaces, BaseEnum.class)){
|
BaseEnum baseEnum = (BaseEnum)obj;
|
statusMapInThisLifeCycle.put(baseEnum.getValue(),baseEnum.getText());
|
}else if(VciBaseUtil.inArray(objInterfaces,BaseEnumInt.class)){
|
BaseEnumInt baseEnum = (BaseEnumInt)obj;
|
statusMapInThisLifeCycle.put(String.valueOf(baseEnum.getValue()),baseEnum.getText());
|
}else{
|
throw new VciBaseException("生命周期所属的类{0}没有实现BaseEnum或者BaseEnumInt的接口,请开发人员改正",new Object[]{className});
|
}
|
}
|
Map<String,String> statusMapInThisLifeCycleLower = new HashMap<String,String>();
|
if(CollectionUtils.isEmpty(statusMapInThisLifeCycle)){
|
throw new VciBaseException("生命周期{0}没有包含任何的状态",new Object[]{className});
|
}
|
for(String statusId : statusMapInThisLifeCycle.keySet()){
|
String statusIdLower = statusId.toLowerCase().trim();
|
String statusText = statusMapInThisLifeCycle.get(statusId);
|
if(!statusDTOMap.containsKey(statusIdLower)){
|
OsStatusDTO statusDTO = new OsStatusDTO();
|
statusDTO.setId(statusId);
|
statusDTO.setName(statusText);
|
statusDTOMap.put(statusIdLower,statusDTO);
|
}
|
statusMapInThisLifeCycleLower.put(statusIdLower,statusText);
|
}
|
if(StringUtils.isBlank(lifeCycleDTO.getStartStatus())){
|
logger.info("因为没有设置生命周期的起始状态,默认第一个状态[{0}]为起始状态,在类{1}中");
|
throw new VciBaseException("没有设置起始状态",new Object[]{});
|
}
|
if(!statusMapInThisLifeCycleLower.containsKey(lifeCycleDTO.getStartStatus().toLowerCase().trim())){
|
throw new VciBaseException("生命周期中的起始状态{0},在类{1}中不存在",new Object[]{lifeCycleDTO.getStartStatus(),className});
|
}
|
lifeCycleDTO.setStartStatusName(statusMapInThisLifeCycleLower.get(lifeCycleDTO.getStartStatus().toLowerCase().trim()));
|
List<OsLifeCycleLineDTO> lineDTOList = new ArrayList<OsLifeCycleLineDTO>();
|
VciLifeCycleTrans[] translations = vciLifeCycle.translations();
|
if(translations != null && translations.length > 0){
|
int lineCount = 1;
|
for(VciLifeCycleTrans line: translations){
|
if(StringUtils.isNotBlank(line.source()) && StringUtils.isNotBlank(line.target())) {
|
VciLifeCycleTranEvent[] listeners = line.listeners();
|
OsLifeCycleLineDTO lineDTO = new OsLifeCycleLineDTO();
|
lineDTO.setSourceLifeStatus(line.source());
|
if(!statusMapInThisLifeCycleLower.containsKey(lineDTO.getSourceLifeStatus().trim().toLowerCase())){
|
throw new VciBaseException("生命周期中连接线的状态{0},在类{1}中不存在",new Object[]{lineDTO.getSourceLifeStatus(),className});
|
}
|
lineDTO.setSourceLifeStatusName(statusMapInThisLifeCycleLower.get(lineDTO.getSourceLifeStatus().trim().toLowerCase()));
|
|
lineDTO.setTargetLifeStatus(line.target());
|
if(!statusMapInThisLifeCycleLower.containsKey(lineDTO.getTargetLifeStatus().trim().toLowerCase())){
|
throw new VciBaseException("生命周期中连接线的状态{0},在类{1}中不存在",new Object[]{lineDTO.getTargetLifeStatus(),className});
|
}
|
lineDTO.setTargetLifeStatusName(statusMapInThisLifeCycleLower.get(lineDTO.getTargetLifeStatus().trim().toLowerCase()));
|
lineDTO.setName(line.name());
|
if(StringUtils.isBlank(lineDTO.getName())){
|
lineDTO.setName("连接线" + lineCount);
|
}
|
if(listeners!=null) {
|
lineDTO.setEventDTOList(Arrays.asList(listeners).stream().map(VciLifeCycleTranEvent::classFullName).collect(Collectors.toList()));
|
}else{
|
lineDTO.setEventDTOList(new ArrayList<String>());
|
}
|
lineCount ++;
|
lineDTOList.add(lineDTO);
|
}
|
}
|
}
|
lifeCycleDTO.setLineDTOList(lineDTOList);
|
lifeCycleDTO.setClassFullName(className);
|
lifeCycleDTOMap.put(lifeCycleDTO.getId().toLowerCase().trim(),lifeCycleDTO);
|
}
|
}
|
|
|
}
|