package foundation.data.object; import java.util.Date; import java.util.List; import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import foundation.dao.Filter; import foundation.dao.ILineLimit; import foundation.dao.LineLimitManager; import foundation.dao.LineLimitType; import foundation.dao.OrderBy; import foundation.dao.Page; import foundation.dao.bizlogic.ICodeProvider; import foundation.data.entity.Entity; import foundation.data.entity.EntitySet; import foundation.data.entity.EntityTree; import foundation.data.entity.LineOperator; import foundation.data.getter.EntityGetter; import foundation.data.getter.EntitySetGetter; import foundation.data.getter.EntityTreeGetter; import foundation.data.loader.DataObjectLoader; import foundation.data.loader.FieldRuleLoader; import foundation.data.meta.MetaMonitor; import foundation.data.meta.ReloadCheckResult; import foundation.data.meta.field.Field; import foundation.data.meta.field.FieldRuntimeCreator; import foundation.data.meta.field.FieldWriter; import foundation.data.meta.field.FieldsRuntime; import foundation.data.meta.field.TableFieldExtensionLoader; import foundation.data.meta.field.TableFieldLoader; import foundation.data.rule.FieldDefaultValueRule; import foundation.data.rule.FieldRules; import foundation.data.rule.FieldValidateRule; import foundation.data.rule.exists.ExistsRule; import foundation.data.rule.exists.ExistsRules; import foundation.data.rule.update.KindredRule; import foundation.data.rule.update.KindredRules; import foundation.handler.IMessageReporter; import foundation.handler.ResultPool; import foundation.persist.NamedSQL; import foundation.persist.SQLRunner; import foundation.persist.source.NamedDataSource; import foundation.server.config.Configer; import foundation.server.config.DBaseType; import foundation.token.IOnlineUser; import foundation.util.ID; import foundation.util.MapList; import foundation.util.Util; import foundation.variant.provider.DataEvent; import foundation.variant.provider.IVariantsProvider; import foundation.variant.provider.VariantProviderType; public class DataObject implements IVariantsProvider { public static LineLimitType DefaultLineLimitType; private static Logger logger; private static DataObjectContainer container; private static boolean IsSequenceActive; private NamedDataSource dataSource; private String id; private String dataName; private String title; private String tableName; private String viewName; private DefaultFilter defaultFilter; private DataJoins dataJoins; private OrderBy defaultOrderBy; private String batchSQL; private String oneSQL; private String countSQL; private SQLGuide sqlGuide; private FieldsRuntime tableFieldMetas; private FieldsRuntime batchBrowseFieldMetas; private FieldsRuntime oneBrowseFieldMetas; private FieldRules fieldRules; private ExistsRules existsRules; private KindredRules kindredRules; private DataObjectVariantsProvider variantsProvider; private Sequence sequence; private Object tableFieldLocker; private Object browseFieldLocker; private MetaMonitor fieldMonitor; private MetaMonitor propertyMonitor; private Date lastObjectUpdateTime; private Date lastFieldLoadTime; static { logger = LogManager.getLogger(DataObject.class); container = DataObjectContainer.getInstance(); IsSequenceActive = Configer.getBoolean("isSequenctActive", false); DefaultLineLimitType = Configer.getBoolean("IsStrictLineLimit", true) ? LineLimitType.Deny : LineLimitType.Free; } public DataObject() throws Exception { defaultFilter = new DefaultFilter(); tableFieldLocker = new Object(); browseFieldLocker = new Object(); variantsProvider = new DataObjectVariantsProvider(this); } public static DataObject getInstance(String dataName) { return container.get(dataName); } public static DataObject getInstance(String dataName, boolean force) { return container.get(dataName, force); } public static DataObject refresh(String dataName) throws Exception { return container.refresh(dataName); } public void load(Entity entity) throws Exception { // 1. id = entity.getString("id"); dataName = entity.getString("name"); tableName = entity.getString("table_name"); viewName = entity.getString("view_name"); defaultFilter.load(entity); title = entity.getString("title"); if (Util.isEmpty(title)) { title = dataName; } // 2. String orderBy = entity.getString("order_by"); if (!Util.isEmpty(orderBy)) { defaultOrderBy = new OrderBy(orderBy); } // 4. batchSQL = entity.getString("batchSQL_name", null); oneSQL = entity.getString("oneSQL_name", null); countSQL = entity.getString("countSQL_name", null); // 5. dataSource = NamedDataSource.getInstance(); // 6. lastObjectUpdateTime = entity.getDate("last_update_time", null); if (lastObjectUpdateTime == null) { lastObjectUpdateTime = new Date(); } } public void build() throws Exception { // 1. build Data Joins if (dataJoins != null) { dataJoins.build(); } // 2. set SQL Guide sqlGuide = new SQLGuide(this); sqlGuide.setBatchSQL(batchSQL); sqlGuide.setOneSQL(oneSQL); sqlGuide.setCountSQL(countSQL); sqlGuide.build(); // 3. if (!Util.isEmpty(tableName)) { sequence = new Sequence(dataSource, tableName); } // 4. 初始化字段描述 tableFieldMetas = null; batchBrowseFieldMetas = null; oneBrowseFieldMetas = null; //5. 加载规则 DBaseType dBaseType = dataSource.getDBaseType(); fieldRules = new FieldRules(dataName); existsRules = ExistsRules.getInstance(dataName, dBaseType); kindredRules = KindredRules.getInstance(dataName, dBaseType); //6. 创建变更检查监听器 fieldMonitor = new MetaMonitor(dataSource, dataName, "getFieldLastUpdateTime"); propertyMonitor = new MetaMonitor(dataSource, dataName, "getPropertyLastUpdateTime"); } public void loadOneDataJoin(DataJoin dataJoin) { if (dataJoins == null) { dataJoins = new DataJoins(); } dataJoins.loadOne(dataJoin); } public Entity getTableEntity(String id) throws Exception { this.getTableFieldMetas(); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), NamedSQL.Code_GetEntity); namedSQL.setTableName(this.tableName); Filter filter = new Filter(); filter = addDefaultFilter(filter.add("id", id)); namedSQL.setFilter(filter); Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.tableFieldMetas)); return result; } public Entity getTableEntity(Filter filter) throws Exception { this.getTableFieldMetas(); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getEntity"); namedSQL.setTableName(this.tableName); namedSQL.setFilter(addDefaultFilter(filter)); Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.tableFieldMetas)); return result; } public Entity getBrowseEntity(String id) throws Exception { this.getOneBrowseFieldMetas(); // 1. get SQL NamedSQL namedSQL = sqlGuide.getBrowseOneSQL(); // 2. get filter Filter filter = new Filter().add(getTableOrViewName() + ".id", id); filter = addDefaultFilter(filter); namedSQL.setFilter(filter); // 3. get data result Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.oneBrowseFieldMetas)); return result; } public Entity getBrowseEntity(Filter filter) throws Exception { this.getOneBrowseFieldMetas(); // 1. get SQL NamedSQL namedSQL = sqlGuide.getBrowseOneSQL(); // 2. get filter filter = addDefaultFilter(filter); namedSQL.setFilter(filter); // 3. get data result Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.oneBrowseFieldMetas)); return result; } public EntitySet getTableEntitySet(IVariantsProvider... providers) throws Exception { this.getTableFieldMetas(); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getEntity"); namedSQL.setTableName(this.tableName); namedSQL.overWriteVariants(addDefaultFilter(providers)); Page page = null; for (IVariantsProvider provider : providers) { if (provider instanceof Page) { page = (Page) provider; } } EntitySet dataSet = SQLRunner.getEntitySet(dataSource, namedSQL, new EntitySetGetter(this.tableFieldMetas)); return getDataByPage(dataSet, page); } private EntitySet getDataByPage(EntitySet dataSet, Page page) { if ((!dataSource.isOracle()) || page == null) { return dataSet; } int pageFrom = page.getBeginRecordNo(), batchStep = page.getPageSize(); int count = dataSet.size(), resultCount = 0; if (pageFrom >= count) { return dataSet; } EntitySet result = new EntitySet(dataSet.getEntityMeta()); for (int recordNo = pageFrom-1; recordNo < count && resultCount < batchStep; recordNo++) { resultCount ++; result.append(dataSet.getEntity(recordNo)); } return result; } public EntitySet getBrowseEntitySet(IVariantsProvider... providers) throws Exception { this.getBatchBrowseFieldMetas(); // 1. get SQL NamedSQL namedSQL = sqlGuide.getBrowseBatchSQL(); // 2. set variants providers = addDefaultFilter(providers); providers = addDefaultOrderBy(providers); namedSQL.setVariants(providers); // 3. try get batch counter BatchCounter counter = null; Page page = null; for (IVariantsProvider provider : providers) { if (provider instanceof BatchCounter) { counter = (BatchCounter) provider; break; }else if (provider instanceof Page) { page = (Page) provider; } } // 4. get data result EntitySet dataSet = SQLRunner.getEntitySet(dataSource, namedSQL, new EntitySetGetter(this.batchBrowseFieldMetas, counter)); return getDataByPage(dataSet, page); } public EntityTree getTableEntityTree(IVariantsProvider... providers) throws Exception { this.getTableFieldMetas(); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getEntity"); namedSQL.setTableName(getTableOrViewName()); namedSQL.setVariants(addDefaultFilter(providers)); EntityTree entityTree = SQLRunner.getEntityTree(dataSource, namedSQL, new EntityTreeGetter(this.tableFieldMetas)); return entityTree; } public EntityTree getBrowseEntityTree(IVariantsProvider... providers) throws Exception { this.getBatchBrowseFieldMetas(); // 1. get SQL NamedSQL namedSQL = sqlGuide.getBrowseBatchSQL(); // 2. get table name and variants providers = addDefaultFilter(providers); namedSQL.setVariants(providers); // 3. get data result EntityTree entityTree = SQLRunner.getEntityTree(dataSource, namedSQL, new EntityTreeGetter(this.batchBrowseFieldMetas)); return entityTree; } public Entity createTableEntity(boolean createDefaultValues) throws Exception { this.getTableFieldMetas(); Entity entity = new Entity(this.tableFieldMetas); if (!createDefaultValues) { return entity; } if (!defaultFilter.isEmpty()) { entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue()); } setEntityDefaultValues(DataEvent.New, entity); return entity; } public Entity cloneEntity(Entity source) throws Exception { if (source == null) { return null; } // 1. 也许是 Table Entity,也许是 Browse Entity,因此取源的字段 Entity result = new Entity(source.getFieldsMeta()); // 2. 填写默认值 if (!defaultFilter.isEmpty()) { result.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue()); } setEntityDefaultValues(DataEvent.New, result); // 3. 复制值 (只复制没有默认值的字段) Object[] dataArray = result.getDataArray(); Object[] sourceArray = source.getDataArray(); int max = dataArray.length; for (int i = 0; i < max; i++) { if (dataArray[i] != null) { continue; } dataArray[i] = sourceArray[i]; } // 4. 重新设置 ID result.set("id", ID.newValue()); return result; } public EntitySet cloneEntitySet(EntitySet source) throws Exception { EntitySet result = new EntitySet(source.getEntityMeta()); for (Entity entity : source) { Entity newOne = cloneEntity(entity); result.append(newOne); } return result; } public Entity createTableEmptyEntity() throws Exception { this.getTableFieldMetas(); Entity entity = new Entity(this.tableFieldMetas); return entity; } public EntitySaver createEntitySaver(Entity original) throws Exception { return new EntitySaver(this, original); } public EntitySaver createEntitySaver(String id) throws Exception { return new EntitySaver(this, id); } public EntitySaver createEntitySaver() throws Exception { return new EntitySaver(this); } public Entity createBrowseEntity(boolean createDefaultValues) throws Exception { this.getOneBrowseFieldMetas(); Entity entity = new Entity(this.oneBrowseFieldMetas); if (!createDefaultValues) { return entity; } if (!defaultFilter.isEmpty()) { entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue()); } setEntityDefaultValues(DataEvent.New, entity); return entity; } public Entity createEmptyBrowseEntity() throws Exception { this.getOneBrowseFieldMetas(); Entity result = new Entity(this.oneBrowseFieldMetas); return result; } public EntitySet createTableEntitySet(int size) throws Exception { this.getTableFieldMetas(); EntitySet result = new EntitySet(this.tableFieldMetas, size); return result; } public EntitySet createTableEntitySet() throws Exception { this.getTableFieldMetas(); EntitySet result = new EntitySet(this.tableFieldMetas); return result; } public EntitySet createBrowseEntitySet() throws Exception { this.getBatchBrowseFieldMetas(); EntitySet result = new EntitySet(this.batchBrowseFieldMetas); return result; } public boolean validateEntity(Entity entity) { return validateEntity(entity, null); } public boolean validateEntity(Entity entity, IMessageReporter reporter) { List validateRules = fieldRules.getValudateRules(); boolean success = true; if (validateRules == null || validateRules.isEmpty()) { return success; } for (FieldValidateRule validateRule : validateRules) { success = success && validateRule.exec(entity, reporter); } return success; } public void setEntityDefaultValues(DataEvent dataEvent, Entity entity) { setEntityDefaultValues(dataEvent, entity, null, null); } public void setEntityDefaultValues(DataEvent dataEvent, Entity entity, IParamProvider paramProvider, IMessageReporter reporter) { List defaultValueRules = fieldRules.getDefaultValueRules(); for (FieldDefaultValueRule valueRule : defaultValueRules) { valueRule.exec(dataEvent, entity, paramProvider, reporter); } } public boolean existsValidate(EntitySet documentSet) throws Exception { boolean detailCheck = false; if (existsRules == null) { return detailCheck; } for (ExistsRule existsRule: existsRules) { EntitySet errorSet = null; if (documentSet == null || !tableName.equalsIgnoreCase(existsRule.getTargetTableName())) { continue; } for (Entity detailEntity : documentSet) { errorSet = existsRule.exec(detailEntity, errorSet); if (errorSet != null && errorSet.size() > 0) { detailCheck = true; } } if (detailCheck) { ResultPool existsCheckResult = ResultPool.getInstance(); existsCheckResult.reportExistsError("existsCheck", existsRule.getName(), errorSet); } } return detailCheck; } public boolean existsValidate(Entity documentEntity) throws Exception { boolean entityCheck = false; existsRules = ExistsRules.getInstance(dataName, dataSource.getDBaseType()); if (existsRules == null) { return entityCheck; } for (ExistsRule existsRule: existsRules) { if (documentEntity == null || !tableName.equalsIgnoreCase(existsRule.getTargetTableName())) { continue; } EntitySet errorSet = null; errorSet = existsRule.exec(documentEntity, errorSet); if (errorSet!= null && errorSet.size() > 0) { entityCheck = true; } if (entityCheck) { ResultPool existsCheckResult = ResultPool.getInstance(); existsCheckResult.reportExistsError("existsCheck", existsRule.getName(), errorSet); } } return entityCheck; } public void updateKindred(Entity entity, IVariantsProvider... providers) throws Exception { kindredRules = KindredRules.getInstance(dataName, DBaseType.MySQL); if (kindredRules == null ){ return; } //1. 获取原始数据 for (KindredRule rule : kindredRules) { if (!rule.isActive()) { logger.info("KindredRule :{}, is not active. Skip", rule.getId()); continue; } int excuteCount = rule.exec(entity, providers); logger.info("dataName:{}, kindredTable: {},kindredTargetField:{} 更新 {} 条.", dataName, rule.getKindredTableName(), rule.getKindredTargetField(), excuteCount); } } public boolean existsEntity(Entity entity) throws Exception { String id = entity.getId(); if (Util.isEmpty(id)) { return false; } Filter filter = new Filter("id", id); filter = addDefaultFilter(filter); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getCount"); namedSQL.setTableName(this.tableName); namedSQL.setFilter(filter); int cnt = SQLRunner.getInteger(dataSource, namedSQL); return cnt > 0; } public boolean existsEntity(String id) throws Exception { if (Util.isEmpty(id)) { return false; } Filter filter = new Filter("id", id); filter = addDefaultFilter(filter); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getCount"); namedSQL.setTableName(this.tableName); namedSQL.setFilter(filter); int cnt = SQLRunner.getInteger(dataSource, namedSQL); return cnt > 0; } public boolean existsEntity(Filter filter) throws Exception { if (filter == null) { return false; } NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getCount"); namedSQL.setTableName(this.tableName); namedSQL.setFilter(addDefaultFilter(filter)); int cnt = SQLRunner.getInteger(dataSource, namedSQL); return cnt > 0; } public int insertEntity(Entity entity) throws Exception { return insertEntity(entity, null, null); } public int insertEntity(Entity entity, IParamProvider paramProvider, IMessageReporter reporter) throws Exception { getTableFieldMetas(); // 1. set id if empty if (entity.isEmptyValue("id")) { String id = ID.newValue(); entity.set("id", id); } // 2. set sequence if (IsSequenceActive && entity.contains("idx")) { long next = sequence.next(); entity.set("idx", next); } // 3. default value setEntityDefaultValues(DataEvent.Insert, entity, paramProvider, reporter); if (!defaultFilter.isEmpty()) { entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue()); } // 4. insert NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), NamedSQL.Code_InsertEntity); namedSQL.setTableName(tableName); namedSQL.setFieldNames(DataEvent.Insert, tableFieldMetas, entity); namedSQL.setFieldValues(DataEvent.Insert, tableFieldMetas, entity); return SQLRunner.execSQL(dataSource, namedSQL); } public int insertEntity(Entity entity, boolean isSimple) throws Exception { if(!isSimple) { return insertEntity(entity); } getTableFieldMetas(); // 1. set id if empty if (entity.isEmptyValue("id")) { String id = ID.newValue(); entity.set("id", id); } // 2. set sequence if (IsSequenceActive && entity.contains("idx")) { long next = sequence.next(); entity.set("idx", next); } if (!defaultFilter.isEmpty()) { entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue()); } // 4. insert NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), NamedSQL.Code_InsertEntity); namedSQL.setTableName(tableName); namedSQL.setFieldNames(DataEvent.Insert, tableFieldMetas, entity); namedSQL.setFieldValues(DataEvent.Insert, tableFieldMetas, entity); return SQLRunner.execSQL(dataSource, namedSQL); } public int insertEntitySet(EntitySet entitySet) throws Exception { if (entitySet == null || entitySet.isEmpty()) { return 0; } // 1. 检查ID是否为空 for (Entity entity : entitySet) { if (entity.isEmptyValue("id")) { entity.set("id", ID.newValue()); } if (!defaultFilter.isEmpty()) { entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue()); } } // 2. 批量插入数据库 FieldsRuntime meta = entitySet.getEntityMeta(); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "insertEntity"); namedSQL.setTableName(this.tableName); namedSQL.setFieldNames(DataEvent.Insert, meta); namedSQL.setPlaceHolders(meta.size()); SQLRunner.saveData(dataSource, namedSQL, entitySet); return entitySet.size(); } public int batchInsertEntitySet(EntitySet entitySet) throws Exception { int result = 0; BatchEntitySaver batchSaver = new BatchEntitySaver(dataSource); result = batchSaver.save(entitySet, this); return result; } public int updateEntity(Entity entity) throws Exception { return updateEntity(entity, DataEvent.Update, null, null); } public int updateEntity(Entity entity, DataEvent event, IParamProvider paramProvider, IMessageReporter reporter) throws Exception { getTableFieldMetas(); // 1. default value if (event == null) { event = DataEvent.Update; } // 2. 填写默认值 setEntityDefaultValues(event, entity, paramProvider, reporter); // 3. 更新数据库 NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "updateById"); namedSQL.setParam("fieldNameId", "id").setParam("id", entity.getId()); namedSQL.setTableName(this.tableName); namedSQL.setFieldNameValues(DataEvent.Update, this.tableFieldMetas, entity); int execCount = SQLRunner.execSQL(namedSQL); // 4. 更新血缘关系表 updateKindred(entity, new Filter("id", entity.getId())); return execCount; } public int updateEntity(Entity entity, Filter filter) throws Exception { //1. NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "updateByCriteria"); namedSQL.setFilter(filter); namedSQL.setTableName(this.tableName); namedSQL.setFieldNameValues(DataEvent.Update, this.tableFieldMetas, entity); int execCount = SQLRunner.execSQL(namedSQL); //2. updateKindred(entity, filter); return execCount; } public void updateByEntity(Entity entity, Filter filter) throws Exception { EntitySaver saver = createEntitySaver(); Object[] dataArray = entity.getDataArray(); FieldsRuntime fieldsMeta = entity.getFieldsMeta(); String[] fieldNames = fieldsMeta.getFieldNames(); for (int i = 0; i < dataArray.length; i++) { saver.set(fieldNames[i], dataArray[i]); } saver.update(filter); } public int saveEntity(Entity entity) throws Exception { return saveEntity(entity, null, null); } public int saveEntity(Entity entity, boolean checkExists) throws Exception { LineOperator operator = entity.getOperator(); if (LineOperator.Delete != operator) { if(existsValidate(entity)) { return 0; } } return saveEntity(entity, null, null); } public int saveEntity(Entity entity, IParamProvider paramProvider, IMessageReporter reporter) throws Exception { if (entity == null) { return 0; } // 1. delete LineOperator operator = entity.getOperator(); if (LineOperator.Delete == operator) { String id = entity.getId(); return this.deleteEntity(id); } // 2. update if (LineOperator.Update == operator) { return this.updateEntity(entity, DataEvent.Update, paramProvider, reporter); } // 3. insert if (LineOperator.Insert == operator) { return this.insertEntity(entity, paramProvider, reporter); } // 4. save boolean exists = this.existsEntity(entity); if (exists) { return this.updateEntity(entity, DataEvent.Update, paramProvider, reporter); } else { return this.insertEntity(entity, paramProvider, reporter); } } public int deleteEntity(String id) throws Exception { if (Util.isEmpty(id)) { return 0; } else { Filter filter = new Filter("id", id); filter = addDefaultFilter(filter); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "deleteByID"); namedSQL.setTableName(this.tableName); namedSQL.setParam("id", id); namedSQL.setFilter(filter); return SQLRunner.execSQL(dataSource, namedSQL); } } public int deleteEntity(Filter filter) throws Exception { filter = addDefaultFilter(filter); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "deleteByCriteria"); namedSQL.setTableName(this.tableName); namedSQL.setFilter(filter); int cnt = SQLRunner.execSQL(dataSource, namedSQL); if (cnt > 1) { logger.error("delete entity {} error: {} deleted", this.tableName, cnt); } return cnt; } public int deleteEntitySet(Filter filter) throws Exception { filter = addDefaultFilter(filter); NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "deleteByCriteria"); namedSQL.setTableName(this.tableName); namedSQL.setFilter(filter); return SQLRunner.execSQL(dataSource, namedSQL); } public int emptyTable() throws Exception { NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "emptyTable"); namedSQL.setTableName(tableName); return SQLRunner.execSQL(dataSource, namedSQL); } public int getCount(IVariantsProvider... providers) throws Exception { getTableFieldMetas(); // 1. get SQL NamedSQL namedSQL = sqlGuide.getCountSQL(providers); // 2. set variants namedSQL.setTableName(getTableOrViewName()); providers = addDefaultFilter(providers); namedSQL.setVariants(null, providers); // 3. get result return SQLRunner.getInteger(dataSource, namedSQL); } public Entity getSummary(String sum, IVariantsProvider... providers) throws Exception { getTableFieldMetas(); NamedDataSource source = dataSource; // 1. get SQL NamedSQL namedSQL = NamedSQL.getInstance(source.getDBaseType(), "getSummary"); // 2. set variants namedSQL.setTableName(getTableOrViewName()); providers = addDefaultFilter(providers); namedSQL.setVariants(null, providers); namedSQL.setParam("sum", sum); // 3. get result Entity entity = SQLRunner.getEntity(source, namedSQL); return entity; } public FieldsRuntime getTableFieldMetas() throws Exception { if (tableFieldMetas == null) { synchronized (tableFieldLocker) { if (tableFieldMetas == null) { loadTableFieldMetas(); } } } return tableFieldMetas; } public FieldsRuntime getBatchBrowseFieldMetas() throws Exception { if (batchBrowseFieldMetas == null) { synchronized (browseFieldLocker) { if (batchBrowseFieldMetas == null) { loadBatchBrowseFieldMetas(); } } } return batchBrowseFieldMetas; } public FieldsRuntime getOneBrowseFieldMetas() throws Exception { if (oneBrowseFieldMetas == null) { synchronized (browseFieldLocker) { if (oneBrowseFieldMetas == null) { loadOneBrowseFieldMetas(); } } } return oneBrowseFieldMetas; } public MapList getBrowseFieldMetas() throws Exception { MapList result = new MapList(); // 1. 先获取 Batch Property FieldsRuntime batchBrowseFieldMetas = getBatchBrowseFieldMetas(); FieldWriter writer; for (Field field : batchBrowseFieldMetas) { writer = field.getWriter(); // 1.1 字段不需要翻译,直接使用 if (!writer.hasDictionaryTranslator()) { result.add(field.getName(), field); continue; } // 1.2 需要翻译的字段, 不包括原始字段 if (!writer.includeOrighinal()) { result.add(field.getName(), field); continue; } // 1.3 需要翻译的字段, 包括原始字段 result.add(field.getName(), field); Field targetField = writer.getTargetField(); if (!batchBrowseFieldMetas.contains(targetField.getName())) { //1.3.1 翻译 result.add(targetField.getName(), targetField); } else { //1.3.2 原有表里面已经有了翻译结果字段,不需要翻译 writer.setActive(false); } } // 2. 如果 One Property 与 Batch Property 不一样,再继续获取 if (!sqlGuide.isBatchAndOneSame()) { FieldsRuntime oneBrowseFieldMetas = getOneBrowseFieldMetas(); for (Field field : oneBrowseFieldMetas) { String fieldName = field.getName(); if (result.contains(fieldName)) { continue; } result.add(fieldName, field); } } return result; } public synchronized void checkObjectMetasReload() throws Exception { boolean changed = false; // 1. 检查Join DataJoins dataJoins = DataObjectLoader.loadOneDataObjectDataJoins(this.dataName); if (dataJoinsChanged(this.dataJoins, dataJoins)) { this.dataJoins = dataJoins; changed = true; } // 2. 检查本身 DataObject objectCreator = DataObjectCreator.ObjectCreator; Entity entity = objectCreator.getTableEntity(id); if (entity != null) { Date lastUpdateTime = entity.getDate("last_update_time", this.lastObjectUpdateTime); if (this.lastObjectUpdateTime.before(lastUpdateTime)) { load(entity); changed = true; } } // 3. 如果需要更新,开始更新 if (changed) { build(); } } private boolean dataJoinsChanged(DataJoins one, DataJoins another) { if (one != null && another != null) { if (one.size() != another.size()) { return true; } Date ontUpdateTime = one.getLastUpdateTime(); Date anotherUpdateTime = another.getLastUpdateTime(); if (ontUpdateTime != null && anotherUpdateTime != null) { return one.equals(another); } return false; } return true; } public void checkFieldMetasReload() throws Exception { ReloadCheckResult checkResult = null; synchronized (tableFieldLocker) { // 1. 更新当前 DataObject checkResult = fieldMonitor.getReloadCheckResult(); if (tableFieldMetas == null || checkResult.isNeedReload()) { loadTableFieldMetas(); fieldMonitor.setLastUpdateTime(checkResult.getLastUpdateTime()); } } // 2. Join DataObject if (dataJoins != null) { for (DataJoin dataJoin : dataJoins) { DataObject joinObject = DataObject.getInstance(dataJoin.getJoinDataName()); synchronized (joinObject.tableFieldLocker) { ReloadCheckResult joinCheckResult = joinObject.fieldMonitor.getReloadCheckResult(); if (joinObject.tableFieldMetas == null || joinCheckResult.isNeedReload()) { joinObject.loadTableFieldMetas(); } } } } // 3. BatchBrowse Field synchronized (browseFieldLocker) { if (batchBrowseFieldMetas == null || checkResult.isNeedReload()) { loadBatchBrowseFieldMetas(); } // 4. OneBrowse Field if (oneBrowseFieldMetas == null || checkResult.isNeedReload()) { loadOneBrowseFieldMetas(); } } } public FieldsRuntime loadTablePhysicsFields() throws Exception { TableFieldLoader fieldLoader = new TableFieldLoader(dataSource, tableName); FieldsRuntime fields = fieldLoader.getFieldsByTableMeta(); return fields; } public void loadTableFieldMetas() throws Exception { // 1. 加载表结构 TableFieldLoader fieldLoader = new TableFieldLoader(dataSource, tableName); tableFieldMetas = fieldLoader.getFieldsByTableResult(); // 2. 加载字段扩展 TableFieldExtensionLoader fieldExtensionLoader = new TableFieldExtensionLoader(dataSource, tableName); EntitySet entitySet = fieldExtensionLoader.load(); // 3. 编译TableFieldMetas FieldRuntimeCreator.buildExtension(tableFieldMetas, entitySet); // 4. rules fieldRules.clear(); FieldRuleLoader.load(tableFieldMetas, fieldRules); // 5. 最后更新时间 lastFieldLoadTime = new Date(); } public void loadBatchBrowseFieldMetas() throws Exception { // 1. 如果 BatchBrowseMeta 与 TableMeta 一样,就取TableMeta if (sqlGuide.isStandard_batch()) { batchBrowseFieldMetas = getTableFieldMetas(); return; } // 2. 加载 loadBrowseBatchMeta表结构 NamedSQL namedSQL = sqlGuide.getBrowseBatchSQL(); Filter filter = new Filter("1", "<>", "1"); namedSQL.setTableName(getTableOrViewName()).setFilter(filter); TableFieldLoader fieldsMetaLoader = new TableFieldLoader(dataSource, tableName); batchBrowseFieldMetas = fieldsMetaLoader.getMetaByNamedSQL(namedSQL); // 3. 加载当前表字段定义 FieldRuntimeCreator.buildExtension(batchBrowseFieldMetas, tableFieldMetas); // 4. 加载关联表字段定义 FieldRuntimeCreator.buildJoinedExtension(batchBrowseFieldMetas); // 5. 最后更新时间 lastFieldLoadTime = new Date(); } public void loadOneBrowseFieldMetas() throws Exception { // 1. 如果 BrowseOneMeta 与 TableMeta 一样,就取TableMeta if (sqlGuide.isStandard_one()) { oneBrowseFieldMetas = getTableFieldMetas(); return; } // 1. 如果 BrowseOneMeta 与 BrowseBatchMeta 一样,就取BrowseBatchMeta if (sqlGuide.isBatchAndOneSame()) { oneBrowseFieldMetas = getBatchBrowseFieldMetas(); return; } // 3. 加载 BrowseOneMeta NamedSQL namedSQL = sqlGuide.getBrowseOneSQL(); Filter filter = new Filter("1", "<>", "1"); namedSQL.setTableName(getTableOrViewName()).setFilter(filter); TableFieldLoader fieldsMetaLoader = new TableFieldLoader(dataSource, tableName); oneBrowseFieldMetas = fieldsMetaLoader.getMetaByNamedSQL(namedSQL); // 4. 加载字段定义 FieldRuntimeCreator.buildExtension(oneBrowseFieldMetas, tableFieldMetas); // 5. 加载关联表字段定义 FieldRuntimeCreator.buildJoinedExtension(oneBrowseFieldMetas); // 5. 最后更新时间 lastFieldLoadTime = new Date(); } public void loadUserLineFilter(IOnlineUser user, Filter filter) throws Exception { String userId = user.getId(); String userCode = user.getCode(); ILineLimit limit = LineLimitManager.getLimit(user, dataName); LineLimitType type = limit != null ? limit.getType() : DefaultLineLimitType; // 1. 如果没有限制 if (LineLimitType.Free == type) { logger.trace("【{}】 line no limit", userCode); return; } // 2. 如果没有任何权限 else if (LineLimitType.Deny == type) { logger.trace("【{}】 line limit deny", userCode); filter.add("1<>1"); return; } // 3. 如果有权限 else if (LineLimitType.Limit == type) { logger.trace("【{}】 line limit active", userCode); String positionField = user.getPositionField(); String positionId = user.getPositionId(); String orgId = user.getOrgId(); String accountId = user.getAccountId(); String companyId = user.getCompanyId(); String buId = user.getBUId(); String actorId = user.getActorId(); NamedSQL limitSQL = limit.getLimitSQL(); limitSQL.setTableName(getTableOrViewName()); limitSQL.setParam("user.id", userId); limitSQL.setParam("user.position_level_field", positionField); limitSQL.setParam("user.position_id", positionId); limitSQL.setParam("user.actor_id", actorId); limitSQL.setParam("user.org_id", orgId); limitSQL.setParam("user.account_id", accountId); limitSQL.setParam("user.company_id", companyId); limitSQL.setParam("user.bu_id", buId); String segment = limitSQL.toString(); filter.add(segment); } } public Filter loadUserLineFilter(IOnlineUser user) throws Exception { Filter filter = new Filter(); loadUserLineFilter(user, filter); return filter; } public NamedDataSource getDataSource() { return dataSource; } public DBaseType getDbaseType() { return dataSource.getDBaseType(); } public String getDataId() { return this.id; } public String getDataName() { return this.dataName; } public String getTitle() { return title; } public String getTableName() { return this.tableName; } public String getViewName() { return this.viewName; } public String getTableOrViewName() { return !Util.isEmpty(this.viewName) ? this.viewName : this.tableName; } public void clearEntityMeta() { this.batchBrowseFieldMetas = null; this.oneBrowseFieldMetas = null; this.tableFieldMetas = null; } public OrderBy getDefaultOrderBy() { return this.defaultOrderBy; } public FieldRules getFieldRules() { return fieldRules; } public List getValidateRules() { return fieldRules.getValudateRules(); } public List getDefaultValueRules() { return fieldRules.getDefaultValueRules(); } public ICodeProvider getCodeProvider() throws Exception { getTableFieldMetas(); return fieldRules.getCodeProvider(); } public void setDataJoins(DataJoins dataJoins) { this.dataJoins = dataJoins; } public boolean hasDataJoins() { if ((dataJoins == null) || dataJoins.isEmpty()) { return false; } return true; } public DataJoins getDataJoins() { return dataJoins; } public int hashCode() { return this.id.hashCode(); } public MetaMonitor getFieldMonitor() { return fieldMonitor; } public MetaMonitor getPropertyMonitor() { return propertyMonitor; } public Date getLastFieldLoadTime() { return lastFieldLoadTime; } public String[] getJoinTables() { if (dataJoins == null || dataJoins.isEmpty()) { return null; } return dataJoins.getJoinTables(); } @Override public String getProviderName() { return variantsProvider.getProviderName(); } @Override public VariantProviderType getProviderType() { return variantsProvider.getProviderType(); } @Override public boolean containsVariant(String name) { return variantsProvider.containsVariant(name); } @Override public Object getVariantValue(DataEvent dataEvent, String name) { return variantsProvider.getVariantValue(dataEvent, name); } @Override public Set getVariantNames() { return variantsProvider.getVariantNames(); } public Filter addDefaultFilter(Filter filter) throws Exception { if (defaultFilter.isEmpty()) { return filter; } if (filter == null) { filter = new Filter(); } filter.add(defaultFilter.getValue(this)); return filter; } private IVariantsProvider[] addDefaultFilter(IVariantsProvider[] providers) throws Exception { if (defaultFilter.isEmpty()) { return providers; } IVariantsProvider[] result = providers; // 1. get filter Filter filter = null; int max = providers.length; for (int i = 0; i < max; i++) { if (providers[i] instanceof Filter) { filter = (Filter) providers[i]; break; } } if (filter != null && filter.containsMark(this)) { return result; } // 2. 如果Provider中没有Filter,需要将Filter加入 if (filter == null) { result = new IVariantsProvider[max + 1]; for (int i = 0; i < max; i++) { result[i] = providers[i]; } result[max] = filter = new Filter(); } // 3. 将默认过滤条件加入Filter filter.add(defaultFilter.getValue(this)); filter.addMark(this); return result; } private IVariantsProvider[] addDefaultOrderBy(IVariantsProvider[] providers) throws Exception { if (defaultOrderBy == null ||defaultOrderBy.isEmpty()) { return providers; } IVariantsProvider[] result = providers; // 1. get filter OrderBy orderBy = defaultOrderBy; int max = providers.length; for (int i = 0; i < max; i++) { if(providers[i] instanceof OrderBy) { orderBy = (OrderBy) providers[i]; break; } } if (orderBy == null) { return result; } // 2. 如果Provider中没有OrderBy,需要将OrderBy加入 if (orderBy != null) { result = new IVariantsProvider[max + 1]; for (int i = 0; i < max; i++) { result[i] = providers[i]; } result[max] = orderBy; } // 3. 将默认过滤条件加入Filter return result; } }