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<String, IPropertyMetasSet> userBuckets;
|
private ConcurrentHashMap<String, SystemMetasBucket> systemContainers;
|
|
static {
|
logger = LogManager.getLogger(DataMetaCenter.class);
|
instance = DataMetaCenter.getInstance();
|
emptyBucket = new MetasEmptySet();
|
templateBucket = PropertyTemplateBucket.getInstance();
|
}
|
|
private DataMetaCenter() {
|
userBuckets = new ConcurrentHashMap<String, IPropertyMetasSet>();
|
systemContainers = new ConcurrentHashMap<String, SystemMetasBucket>();
|
}
|
|
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<String> 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<String> 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<String> 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<String> 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<String> 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<String> includeFields, ReloadCheckResult templateCheckResult) throws Exception {
|
String dataName = dataObject.getDataName();
|
boolean changed = false;
|
|
//1. 检查字段说明是否需要更新
|
if (templateCheckResult == null) {
|
templateCheckResult = checkTemplateAndIndexReload();
|
}
|
|
//2. 获取数据对象的BrowseProperty
|
MapList<String, Field> 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;
|
}
|
|
}
|