package foundation.data.meta; import java.util.Date; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import foundation.dao.Filter; import foundation.data.entity.Entity; import foundation.data.entity.EntitySet; import foundation.data.meta.field.Field; import foundation.data.meta.field.FieldExtension; import foundation.data.meta.field.FieldsRuntime; import foundation.data.meta.property.IPropertyMetasSet; import foundation.data.meta.property.Level; import foundation.data.meta.property.MetaCode; import foundation.data.meta.property.MetaType; import foundation.data.meta.property.MetasEmptySet; import foundation.data.meta.property.Property; import foundation.data.meta.property.PropertysLoader; import foundation.data.meta.property.PropertysRuntime; import foundation.data.meta.property.SystemMetasBucket; import foundation.data.meta.template.PropertyTemplate; import foundation.data.meta.template.PropertyTemplateBucket; import foundation.data.object.DataObject; import foundation.persist.SQLRunner; import foundation.util.MapList; public class DataMetaCenter { protected static Logger logger; private static DataMetaCenter instance; private static MetasEmptySet emptyBucket; private static PropertyTemplateBucket templateBucket; private ConcurrentHashMap userBuckets; private ConcurrentHashMap systemContainers; static { logger = LogManager.getLogger(DataMetaCenter.class); instance = DataMetaCenter.getInstance(); emptyBucket = new MetasEmptySet(); templateBucket = PropertyTemplateBucket.getInstance(); } private DataMetaCenter() { userBuckets = new ConcurrentHashMap(); systemContainers = new ConcurrentHashMap(); } public static synchronized DataMetaCenter getInstance() { if (instance == null) { instance = new DataMetaCenter(); } return instance; } //0. 系统启动的时候,有配置的用户会将该用户的索引加载到系统,但是没有初始化 public PropertysRuntime getOnePropertyMetas(MetaCode metaCode) throws Exception { IPropertyMetasSet metasSet = null; //1. 检查Property字段说明是否需要更新 checkIndexReload(); //2. 从用户(用户+角色+场景)配置中获取 DataObject dataObject = metaCode.getDataObject(); Date date = dataObject.getLastFieldLoadTime(); MetaType type = metaCode.getType(); String userKey = metaCode.getUserKey(); metasSet = userBuckets.get(userKey); MetaMonitor metaMonitor = dataObject.getPropertyMonitor(); ReloadCheckResult checkResult = metaMonitor.getReloadCheckResult(); if (metasSet != null && metasSet.isInitialized(date) && !checkResult.isNeedReload()) { return metasSet.getPropertys(type); } //3. 加锁,进入计算逻辑 synchronized (dataObject) { //3.1 如果其他线程完成任务,直接使用并退出 if (metasSet == null) { metasSet = userBuckets.get(userKey); } if (metasSet != null && metasSet.isInitialized(date) && !checkResult.isNeedReload()) { if (!checkResult.noChange(metaMonitor.getLastUpdateTime())) { return metasSet.getPropertys(type); } } //3.2 获取系统 Meta,传递给用户Meta String dataName = metaCode.getDataName(); SystemMetasBucket systemMetasContainer = systemContainers.get(dataName); if (systemMetasContainer == null) { systemMetasContainer = new SystemMetasBucket(dataObject, templateBucket); systemContainers.put(dataName, systemMetasContainer); } PropertysLoader metasLoader = new PropertysLoader(dataObject); metasLoader.load(systemMetasContainer); metaMonitor.setLastUpdateTime(checkResult.getLastUpdateTime()); metasSet = systemMetasContainer.getMetasBucket(metaCode); if (metasSet != null) { IPropertyMetasSet master = systemMetasContainer.getMasterPropertys(Level.Capacity, metaCode); metasSet.build(master); userBuckets.put(userKey, metasSet); return metasSet.getPropertys(type); } //3.3 如果没有定义,返回空 Property(下次只要从用户配置中就可以得知没有配置) userBuckets.put(userKey, emptyBucket); return null; } } public void saveUserPropertys(MetaCode metaCode) { } public void saveCapacityPropertys(MetaCode metaCode) { } public void deleteUserPropertys(MetaCode metaCode) { } public void deleteCapacityPropertys(MetaCode metaCode) { } public static void synchronizMetas(String tablePrefix) throws Exception { //1. 检查字段说明是否需要更新 ReloadCheckResult templateCheckResult = checkTemplateAndIndexReload(); //2. 获取所有表 List tableList = SQLRunner.getTableList(); //3. 同步所有字段 synchronizFields(tablePrefix, tableList, templateCheckResult); //4. 同步所有属性 synchronizPropertys(tablePrefix, tableList, templateCheckResult); //5. 输出结果 logger.debug("同步完成,共同步{}个表", tableList.size()); } public static void synchronizFields(String tablePrefix, List tableList, ReloadCheckResult templateCheckResult) throws Exception { //1. 检查字段说明是否需要更新 if (templateCheckResult == null) { templateCheckResult = checkTemplateAndIndexReload(); } //2. 获取所有表 if (tableList == null) { tableList = SQLRunner.getTableList(); } //3. 同步字段 for (String table: tableList) { if (tablePrefix != null && !table.startsWith(tablePrefix)) { continue; } DataObject dataObject = DataObject.getInstance(table); synchronizOneObjectFields(dataObject, null, templateCheckResult); } } public static void synchronizPropertys(String tablePrefix, List tableList, ReloadCheckResult templateCheckResult) throws Exception { //1. 检查字段说明是否需要更新 if (templateCheckResult == null) { templateCheckResult = checkTemplateAndIndexReload(); } //2. 获取所有表 if (tableList == null) { tableList = SQLRunner.getTableList(); } //3. 同步属性 for (String table: tableList) { if (tablePrefix != null && !table.startsWith(tablePrefix)) { continue; } DataObject dataObject = DataObject.getInstance(table); synchronizOneObjectPropertys(dataObject, null, templateCheckResult); } } public static void synchronizOneObjectMeta(DataObject dataObject, Set includeFields, ReloadCheckResult templateCheckResult) throws Exception { //1. 检查DataObject本身和Join定义是否需要刷新 dataObject.checkObjectMetasReload(); //2. 检查字段说明是否需要更新 if (templateCheckResult == null) { templateCheckResult = checkTemplateAndIndexReload(); } //3. 同步字段 synchronizOneObjectFields(dataObject, includeFields, templateCheckResult); //4. 同步属性 synchronizOneObjectPropertys(dataObject, includeFields, templateCheckResult); } public static void synchronizOneObjectFields(DataObject dataObject, Set includeFields, ReloadCheckResult templateCheckResult) throws Exception { String dataName = dataObject.getDataName(); boolean changed = false; //1. 检查字段说明是否需要更新 if (templateCheckResult == null) { templateCheckResult = checkTemplateAndIndexReload(); } //2. 获取表物理结构 FieldsRuntime fields = dataObject.loadTablePhysicsFields(); //3. get data object field DataObject fieldObject = DataObject.getInstance("sys_data_field"); Filter filter = new Filter("dataName", dataName); EntitySet entitySet = fieldObject.getTableEntitySet(filter); //4. 扩展定义中有,物理结构中没有删除掉 for (Entity entity: entitySet) { String fieldName = entity.getString("field_name"); if (includeFields != null && !includeFields.contains(fieldName)) { continue; } if (!fields.contains(fieldName)) { String id = entity.getId(); fieldObject.deleteEntity(id); changed = true; } } //5. 物理结构中有,扩展定义中没有添加进来, 如果有但是内容不一致修改 for (Field field: fields) { String fieldName = field.getName(); if (includeFields != null && !includeFields.contains(fieldName)) { continue; } Entity entity = entitySet.getEntity("field_name", fieldName); //5.1 如果定义中不存在,添加定义 if (entity == null) { entity = fieldObject.createTableEntity(true); PropertyTemplate fieldTemplate = templateBucket.getOneTemplate(fieldName); FieldExtension.toEntity(dataName, field, entity, fieldTemplate); fieldObject.insertEntity(entity); changed = true; continue; } //5.2 如果定义与物理字段实际情况不符合,修改定义 } //6. 如果有改变,通知DataObject if (changed) { MetaMonitor metaMonitor = dataObject.getFieldMonitor(); metaMonitor.setRefreshFlag(); } } public static void synchronizOneObjectPropertys(DataObject dataObject, Set includeFields, ReloadCheckResult templateCheckResult) throws Exception { String dataName = dataObject.getDataName(); boolean changed = false; //1. 检查字段说明是否需要更新 if (templateCheckResult == null) { templateCheckResult = checkTemplateAndIndexReload(); } //2. 获取数据对象的BrowseProperty MapList browseFields = dataObject.getBrowseFieldMetas(); //3. get data object property DataObject propertyObject = DataObject.getInstance("sys_data_property"); Filter filter = new Filter("dataName", dataName); EntitySet entitySet = propertyObject.getTableEntitySet(filter); //4. 定义中有(且不是虚拟属性),字段中没有,删除掉 for (Entity entity: entitySet) { String fieldName = entity.getString("field_name"); if (includeFields != null && !includeFields.contains(fieldName)) { continue; } if (entity.getBoolean("is_virtual", false)) { continue; } if (!browseFields.contains(fieldName)) { String id = entity.getId(); propertyObject.deleteEntity(id); changed = true; } } //5. 字段中有,定义中没有,添加进来, 如果有但是内容不一致修改 for (Field field: browseFields) { String fieldName = field.getName(); if (includeFields != null && !includeFields.contains(fieldName)) { continue; } if (Property.ExcludeFields.contains(fieldName)) { continue; } Entity entity = entitySet.getEntity("field_name", fieldName); //5.1 如果定义中不存在,添加定义 if (entity == null) { entity = propertyObject.createTableEntity(true); PropertyTemplate propertyTemplate = templateBucket.getOneTemplate(fieldName); Property.toEntity(dataName, field, entity, propertyTemplate); propertyObject.insertEntity(entity); changed = true; continue; } //5.2 如果定义与物理字段实际情况不符合,修改定义 } //6. 如果有改变,通知DataObject if (changed) { MetaMonitor metaMonitor = dataObject.getPropertyMonitor(); metaMonitor.setRefreshFlag(); } } private static ReloadCheckResult checkIndexReload() throws Exception { MetaMonitor indexMonitor = templateBucket.getIndexMonitor(); ReloadCheckResult checkResult = indexMonitor.getReloadCheckResult(); if (checkResult.isNeedReload()) { synchronized (templateBucket) { if (checkResult.noChange(indexMonitor.getLastUpdateTime())) { templateBucket.reloadIndex(); indexMonitor.setLastUpdateTime(checkResult.getLastUpdateTime()); } } } return checkResult; } private static ReloadCheckResult checkTemplateAndIndexReload() throws Exception { MetaMonitor templateMonitor = templateBucket.getTemplateAndIndexMonitor(); ReloadCheckResult checkResult = templateMonitor.getReloadCheckResult(); if (checkResult.isNeedReload()) { synchronized (templateBucket) { if (checkResult.noChange(templateMonitor.getLastUpdateTime())) { templateBucket.loadTemplateAndIndex(); templateMonitor.setLastUpdateTime(checkResult.getLastUpdateTime()); } } } return checkResult; } }