/** * Alipay.com Inc. * Copyright (c) 2004-2012 All Rights Reserved. */ package com.alipay.zdal.rule.bean; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.apache.log4j.Logger; import com.alipay.zdal.common.DBType; import com.alipay.zdal.rule.LogicTableRule; import com.alipay.zdal.rule.ruleengine.entities.abstractentities.ListSharedElement; import com.alipay.zdal.rule.ruleengine.entities.abstractentities.OneToManyEntry; import com.alipay.zdal.rule.ruleengine.entities.abstractentities.RuleChain; import com.alipay.zdal.rule.ruleengine.entities.abstractentities.SharedElement; import com.alipay.zdal.rule.ruleengine.entities.abstractentities.TablePropertiesSetter; import com.alipay.zdal.rule.ruleengine.entities.convientobjectmaker.DatabaseMapProvider; import com.alipay.zdal.rule.ruleengine.entities.convientobjectmaker.TableMapProvider; import com.alipay.zdal.rule.ruleengine.entities.inputvalue.CalculationContextInternal; import com.alipay.zdal.rule.ruleengine.entities.retvalue.TargetDB; import com.alipay.zdal.rule.ruleengine.rule.Field; import com.alipay.zdal.rule.ruleengine.rule.ListAbstractResultRule; /** * һ������� * * û�в��������Ȼ����map��Ӧ����Ӧ�����ݿ�ȥ��ԭ�������� 1.����ֱ��߼��ͷֿ��߼���ȫ��ͬ��������簴��idȡģ+gmtʱ��� 2.ȫ��full * scan��ѯ��ʱ�������ѡ�����п��ܵı�Ȼ����map��Ӧ�����ݿ����ʱ�Ķ�Ӧ������ 3.����ҵ���������ñ��ڱ����ĸ�ʽ�� * * * * */ public class LogicTable extends ListSharedElement implements Cloneable, LogicTableRule, TablePropertiesSetter { private static final Logger log = Logger.getLogger(LogicTable.class); private OneToManyEntry oneToManyEntry = new OneToManyEntry(); /** * ͨ���򵥷�������databaseMap */ private DatabaseMapProvider databaseMapProvider = null; /** * ��type */ private DBType dbType = DBType.MYSQL; /** * ��������� */ private boolean allowReverseOutput; /** * Ψһ���������ȼ��ġ����ȼ��ߵģ�����List��ǰ�� ÿ�������Ψһ����֧�ֶ�����������������ĸ�����ǣ�����������������Ŀǰ�����Ƕ��Ψһ�� * ����List�е�ÿ��Set����ֻ����һ��Ԫ�ء���ÿ������һ��Ψһ�� * * ��һ��SQL����ʱ�������ȼ�������list����һ����sql�ж������ļ������ӦΨһ����������Ϊ�������Ψһ���������� */ private List<String> uniqueKeys; /** * �����ǰû����Ըñ���Զ���⣬��ô�������ɳ����Ŀ�ֱ��ָ����subSharedElement���á� * �����ǰ�Ѿ������Զ���⣬��ô���Զ�����������ӵ����ɳ���Map��(���key��ͬ ���Զ����database����Ḳ���Զ����ɳ����Ķ���) * * ��һ���������Ҫ���ǣ�Ҳ����˵��������������Զ�����database���� * ����ȫ��database������Ȼϣ��ȫ��database���󸲸��Զ����ӹ���(�������壬�α�д�ӹ����أ��� * ����һ���������ȫ�ֶ���Ҳ���Ӷ���ϣ��������Ӷ�����ôȫ��ƴװ����mapʧЧ�� * �������ֱ��ɾ��ȫ��ƴװdatabaseMap��provider����ͺ��ˡ� * * @param generatedDatabaseMap * @return */ @SuppressWarnings("unchecked") protected Map<String, Database> buildSubSharedMap(Map<String, Database> generatedDatabaseMap) { if (this.subSharedElement == null || this.subSharedElement.size() == 0) { // �����ǰû���Զ���ı������ֱ��ʹ�����ɺ��map if (log.isDebugEnabled()) { log .debug("subShared element is null ,use sharedElement generated by database shared element map provider."); } return generatedDatabaseMap; } else { if (log.isDebugEnabled()) { log .debug("subSharedElement is not null,putAll current subSharedElement to generated sharedElement"); } Map<String, Database> beAppendMap = (Map<String, Database>) subSharedElement; generatedDatabaseMap.putAll(beAppendMap); } if (log.isDebugEnabled()) { log.debug("sub shared element is " + generatedDatabaseMap); } return generatedDatabaseMap; } public Object clone() throws CloneNotSupportedException { return super.clone(); } public DatabaseMapProvider getDatabaseMapProvider() { return databaseMapProvider; } public Set<RuleChain> getRuleChainSet() { return ruleChainSet; } /** * @see com.alipay.zdal.rule.ruleengine.entities.abstractentities.ListSharedElement#init() */ public void init() { // ��ʼ�����ݿ�ڵ� initDatabaseByDatabaseMapProvider(); //�ж�subSharedElement ���벻Ϊ�� if (subSharedElement == null || subSharedElement.isEmpty()) { throw new IllegalArgumentException("���ٱ���ָ��һ����"); } oneToManyEntry.init(); //��oneToManyEntry �ŵ�����dataSource����ȥ����ʵsubSharedElement һ��ʼ��ŵ���<string,database> for (Entry<String, ? extends SharedElement> sharedElement : subSharedElement.entrySet()) { sharedElement.getValue().put(oneToManyEntry); } // ��ʼ������ super.init(); registeRule(ruleChainSet); if (log.isDebugEnabled()) { log.debug("rule chain set [" + ruleChainSet + "] inited;"); } } protected void initDatabaseByDatabaseMapProvider() { if (databaseMapProvider != null) { Map<String, Database> generatedDatabaseMap = databaseMapProvider.getDatabaseMap(); if (generatedDatabaseMap != null) { subSharedElement = buildSubSharedMap(generatedDatabaseMap); } } } /** * ֵ̽���� */ private Set<RuleChain> ruleChainSet = new HashSet<RuleChain>(); public void setDatabase(Map<String, SharedElement> databasesMap) { if (databasesMap != null) { super.subSharedElement = databasesMap; } } public void setDatabaseMapProvider(DatabaseMapProvider databaseMapProvider) { this.databaseMapProvider = databaseMapProvider; } public void setDatabaseRule(List<ListAbstractResultRule> databaseRule) { RuleChainImp ruleChainImp = new RuleChainImp(); ruleChainImp.setListResultRule(databaseRule); ruleChainImp.setDatabaseRuleChain(true); ruleChainImp.init(); this.listResultRule = ruleChainImp; } /** * ����ȫ��ȫ�� * * @return ��null ������Դ����� * */ @SuppressWarnings("unchecked") public List<TargetDB> getAllTargetDBList() { List<TargetDB> targetDatabases = new ArrayList<TargetDB>(); Map<String, Database> beingSelectedDatabases = (Map<String, Database>) getSubSharedElements(); for (Database database : beingSelectedDatabases.values()) { TargetDB db = new TargetDB(); db.setDbIndex(database.getDataSourceKey()); Set<String> tempTableNameSet = new HashSet<String>(); Map<String, SharedElement> tablesMap = database.getTables(); Collection<? extends SharedElement> tableSharedElement = tablesMap.values(); for (SharedElement shearedElement : tableSharedElement) { Table table = (Table) shearedElement; tempTableNameSet.add(table.getTableName()); } db.setTableNames(tempTableNameSet); targetDatabases.add(db); } return targetDatabases; } // public DBType getDBType() { // return dbType; // } public void setDBType(DBType dbType) { this.dbType = dbType; } public boolean isAllowReverseOutput() { return this.allowReverseOutput; } public void setAllowReverseOutput(boolean allowReverseOutput) { this.allowReverseOutput = allowReverseOutput; } public List<String> getUniqueColumns() { return uniqueKeys; } public List<String> getUniqueKeys() { return uniqueKeys; } public void setUniqueKeys(List<String> uniqueKeys) { this.uniqueKeys = uniqueKeys; } /** * ���ⲿ���õĽӿڡ� * ���ڷ��طֿ�ֱ�Ľ�� * * �����LogicTable����û�й��򣬼ȶ�Ӧ��logicTableû�зֿ����, * ������Ȼ�й��򣬵��ǵ�ǰ��sql������û��ƥ�䵽��Щ���򣬷���������������� * a ���logicTale����ֻ��һ���⣬��ô����Ĭ�Ϲ���Ϊ�ζ�Ӧ��ȡ���ÿ⡣���������Ҫ�����ڵ��⣨��,�ࣩ���򣨵����ࣩ�� ���������¡� * b ���logicTale�ж���⣬��ôӦ��ʹ�� ��ѡ����ԣ�DEFAULT_LIST_RESULT_STRAGETY�������������������ΪDEFAULT_LIST_RESULT_STRAGETY.NONE�Ƚϰ�ȫ; * ��������˹���ֱ��ʹ�ù�����м��㡣 */ public List<TargetDB> calculate(Map<RuleChain, CalculationContextInternal> map) { CalculationContextInternal calculationContext = map.get(this.listResultRule); Map<String/* �����ֵ */, Field> resultmap = null; if (calculationContext == null) { //����Ϊ�գ����߹���δƥ�䵽 if (subSharedElement != null && subSharedElement.size() == 1) { // 1���ڹ���δƥ�䵽����sharedElementΨһ������£�Ĭ�ϵ�ѡ��Ψһ��sharedElement. //��ʱ���������ΪNONE��Ҳ��ѡ��Ψһ�ģ�����ʹ��Ĭ�Ϲ��� resultmap = buildSingleDatabase(); } else { //2)����Ϊ�գ�����δƥ�䵽������Ĭ���ӿⲻΪΨһ��һ��������£�ʹ��Ĭ�Ϲ��� resultmap = buildDefaultDatabaseMap(); } } else { //3�� ListAbstractResultRule rule = calculationContext.ruleChain .getRuleByIndex(calculationContext.index); resultmap = rule.eval(calculationContext.sqlArgs); } List<TargetDB> targetDBList = buildTargetDBList(map, resultmap); return targetDBList; } final Map<String, Field> buildDefaultDatabaseMap() { Map<String, Field> resultmap; resultmap = new HashMap<String, Field>(defaultListResult.size()); for (String defaultIndex : defaultListResult) { resultmap.put(defaultIndex, Field.EMPTY_FIELD); } return resultmap; } final List<TargetDB> buildTargetDBList(Map<RuleChain, CalculationContextInternal> map, Map<String, Field> resultmap) { List<TargetDB> targetDBList = new ArrayList<TargetDB>();//�������б� for (Entry<String, Field> entry : resultmap.entrySet()) { Database database = (Database) subSharedElement.get(entry.getKey()); if (database == null) { throw new IllegalArgumentException("���ܸ���key: " + entry.getKey() + "ȡ����Ӧ�ı�������ǰ�ӹ��������б���Ϊ:" + subSharedElement); } else { //��ӱ��� TargetDB targetDB = new TargetDB(); String dbKey = database.getDataSourceKey(); if (dbKey == null) { throw new IllegalArgumentException("database���󲻰�������Դkey id"); } targetDB.setDbIndex(dbKey); database.calculateTable(targetDB, entry.getValue(), map); targetDBList.add(targetDB); } } return targetDBList; } final Map<String, Field> buildSingleDatabase() { Map<String, Field> resultmap; resultmap = new HashMap<String, Field>(1); for (String key : subSharedElement.keySet()) { resultmap.put(key, Field.EMPTY_FIELD); } return resultmap; } public void setLogicTableName(String logicTable) { oneToManyEntry.setLogicTableName(logicTable); } public String getLogicTableName() { return oneToManyEntry.getLogicTableName(); } public void setTableRuleChain(RuleChain ruleChain) { oneToManyEntry.setTableRuleChain(ruleChain); } public void setTableMapProvider(TableMapProvider tableMapProvider) { oneToManyEntry.setTableMapProvider(tableMapProvider); } public TableMapProvider getTableMapProvider() { return oneToManyEntry.getTableMapProvider(); } @Override public String toString() { return "LogicTable [allowReverseOutput=" + allowReverseOutput + ", databaseMapProvider=" + databaseMapProvider + ", dbType=" + dbType + ", uniqueKeys=" + uniqueKeys + ", defaultListResult=" + defaultListResult + ", defaultListResultStragety=" + defaultListResultStragety + ", listResultRule=" + listResultRule + ", subSharedElement=" + subSharedElement + "]"; } public void setDefaultListResultStragety(DEFAULT_LIST_RESULT_STRAGETY defaultListResultStragety) { // �����˸����ͬ�������� super.setDefaultListResultStragety(defaultListResultStragety); oneToManyEntry.setDefaultListResultStragety(defaultListResultStragety); } public void setTableRule(List<ListAbstractResultRule> tableRule) { oneToManyEntry.setTableRule(tableRule); } public List<ListAbstractResultRule> getTableRule() { return oneToManyEntry.getTableRule(); } }