|
@@ -0,0 +1,654 @@
|
|
|
+package nc.vo.bd.accessor;
|
|
|
+
|
|
|
+import java.io.Serializable;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.Enumeration;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.concurrent.locks.ReadWriteLock;
|
|
|
+import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
+
|
|
|
+import javax.swing.tree.DefaultMutableTreeNode;
|
|
|
+import javax.swing.tree.DefaultTreeModel;
|
|
|
+import javax.swing.tree.TreeNode;
|
|
|
+
|
|
|
+import nc.pubitf.bd.accessor.IAccessorQueryService;
|
|
|
+import nc.pubitf.bd.accessor.IAccessorVisibleUtil;
|
|
|
+import nc.pubitf.bd.accessor.IGeneralAccessor;
|
|
|
+import nc.vo.bd.access.tree.AbastractTreeCreateStrategy;
|
|
|
+import nc.vo.bd.access.tree.BDTreeCreator;
|
|
|
+import nc.vo.bd.pub.BDCacheFactory;
|
|
|
+import nc.vo.bd.pub.BDCacheMiscUtil;
|
|
|
+import nc.vo.cache.ICache;
|
|
|
+import nc.vo.pub.BusinessException;
|
|
|
+
|
|
|
+import nccloud.commons.collections.CollectionUtils;
|
|
|
+import nccloud.commons.lang.StringUtils;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 树型结构的数据访问器
|
|
|
+ *
|
|
|
+ * @author liujian
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class HierachicalDataAccessor implements IGeneralAccessor {
|
|
|
+
|
|
|
+ static class CoreData implements Serializable{
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
+
|
|
|
+ private Set<String> cachedOrgs = new HashSet<String>();
|
|
|
+
|
|
|
+ private DefaultTreeModel model;
|
|
|
+
|
|
|
+ private Map<String, DefaultMutableTreeNode> pk_treenode_map = new HashMap<String, DefaultMutableTreeNode>();
|
|
|
+
|
|
|
+ private String version;
|
|
|
+
|
|
|
+ CoreData(List<IBDData> datas, String version) {
|
|
|
+ // 构造树结构
|
|
|
+ model = BDTreeCreator.createTree(datas.toArray(new IBDData[0]),
|
|
|
+ new TreeStrategy());
|
|
|
+ // 构造主键_树结点_map, 并记录组织集合
|
|
|
+ pk_treenode_map = hashlizeTreeModel(model);
|
|
|
+ this.version = version;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回所有缓存的IHierachicalData数据.
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ List<IBDData> extractDatas() {
|
|
|
+ Map<String, DefaultMutableTreeNode> map = pk_treenode_map;
|
|
|
+ Collection<DefaultMutableTreeNode> vs = map.values();
|
|
|
+ List<IBDData> datas = new ArrayList<IBDData>();
|
|
|
+
|
|
|
+ for (DefaultMutableTreeNode node : vs) {
|
|
|
+ datas.add((IBDData) node.getUserObject());
|
|
|
+ }
|
|
|
+ return datas;
|
|
|
+ }
|
|
|
+
|
|
|
+ DefaultTreeModel getModel() {
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据主键查询树结点
|
|
|
+ *
|
|
|
+ * @param pk
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ DefaultMutableTreeNode getNodeByPk(String pk) {
|
|
|
+ DefaultMutableTreeNode node = pk_treenode_map.get(pk);
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+
|
|
|
+ String getVersion() {
|
|
|
+ return version;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造主键_树结点_map, 并记录组织集合
|
|
|
+ *
|
|
|
+ * @param m
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private Map<String, DefaultMutableTreeNode> hashlizeTreeModel(
|
|
|
+ DefaultTreeModel m) {
|
|
|
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
|
|
|
+
|
|
|
+ Enumeration<DefaultMutableTreeNode> e = root.preorderEnumeration();
|
|
|
+ e.nextElement();
|
|
|
+ Map<String, DefaultMutableTreeNode> result = new HashMap<String, DefaultMutableTreeNode>();
|
|
|
+ while (e.hasMoreElements()) {
|
|
|
+ DefaultMutableTreeNode node = e.nextElement();
|
|
|
+ if (node.getUserObject() instanceof IBDData) {
|
|
|
+ IBDData data = (IBDData) node.getUserObject();
|
|
|
+ data.setLevel(node.getLevel());
|
|
|
+ // data.setLeaf(node.isLeaf());
|
|
|
+ result.put(data.getPk(), node);
|
|
|
+ cachedOrgs.add(data.getPk_org());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 指定组织的数据是否已经缓存.
|
|
|
+ *
|
|
|
+ * @param pk_org
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean isOrgCached(String pk_org) {
|
|
|
+ return cachedOrgs.contains(pk_org);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class TreeStrategy extends AbastractTreeCreateStrategy {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getCodeRule() {
|
|
|
+ return "2/2/2"; // 现在除科目外的所有档案均为主键树,此方法无意义
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object getCodeValue(Object obj) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object getNodeId(Object obj) {
|
|
|
+ if (obj instanceof IBDData) {
|
|
|
+ IBDData data = (IBDData) obj;
|
|
|
+ return data.getPk();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object getParentNodeId(Object obj) {
|
|
|
+ if (obj instanceof IBDData) {
|
|
|
+ IBDData data = (IBDData) obj;
|
|
|
+ return data.getParentPk();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isCodeTree() {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final String COREDATA_CACHE_KEY = "CoreDataCacheKey";
|
|
|
+
|
|
|
+ private String beanid;
|
|
|
+
|
|
|
+ private CoreData coreData = null;
|
|
|
+
|
|
|
+ private Map<String, CoreData> coreDataCacheMap = null;
|
|
|
+
|
|
|
+ private IGeneralAccessor generalAccesor;
|
|
|
+
|
|
|
+ private Set<String> loadedOrg = new HashSet<String>();
|
|
|
+
|
|
|
+ private IAccessorQueryService queryService = new HierachicalDataCacheService();
|
|
|
+
|
|
|
+ private ReadWriteLock rwlock = new ReentrantReadWriteLock();
|
|
|
+
|
|
|
+ private IAccessorVisibleUtil visibleUitl = AccessorVisibleScopeUtil
|
|
|
+ .getInstance();
|
|
|
+
|
|
|
+ protected HierachicalDataAccessor() {
|
|
|
+ }
|
|
|
+
|
|
|
+ public HierachicalDataAccessor(String beanid) {
|
|
|
+ this.beanid = beanid;
|
|
|
+ generalAccesor = new GeneralAccessor(beanid);
|
|
|
+ initCoreData();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void clearCacheData() {
|
|
|
+ setCoreData(new CoreData(new ArrayList<IBDData>(), ""));
|
|
|
+ generalAccesor.clearCacheData();
|
|
|
+ }
|
|
|
+
|
|
|
+ private IBDData clone(IBDData data) {
|
|
|
+ if (data == null)
|
|
|
+ return null;
|
|
|
+ return data.clone();
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<IBDData> clone(List<IBDData> datas) {
|
|
|
+ if (datas == null || datas.size() == 0)
|
|
|
+ return null;
|
|
|
+ List<IBDData> result = new ArrayList<IBDData>();
|
|
|
+ for (IBDData data : datas) {
|
|
|
+ result.add(clone(data));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ArrayList<IBDData> combineDatas(List<IBDData> datasInCache,
|
|
|
+ List<IBDData> datas) {
|
|
|
+ Map<String, IBDData> pk_data_map = new HashMap<String, IBDData>();
|
|
|
+ for (IBDData data : datasInCache) {
|
|
|
+ pk_data_map.put(data.getPk(), data);
|
|
|
+ }
|
|
|
+ for (IBDData data : datas) {
|
|
|
+ pk_data_map.put(data.getPk(), data);
|
|
|
+ }
|
|
|
+
|
|
|
+ ArrayList<IBDData> result = new ArrayList<IBDData>();
|
|
|
+ result.addAll(pk_data_map.values());
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unused")
|
|
|
+ private ArrayList<String> extractPKs(List<IBDData> datas) {
|
|
|
+ ArrayList<String> pks = new ArrayList<String>();
|
|
|
+ for (IBDData data : datas) {
|
|
|
+ pks.add(data.getPk());
|
|
|
+ }
|
|
|
+ return pks;
|
|
|
+ }
|
|
|
+
|
|
|
+ private DefaultMutableTreeNode findNodeByPkLoadDataIfNecessary(
|
|
|
+ String pk_org, String pk_doc) {
|
|
|
+ if (pk_doc == null)
|
|
|
+ return null;
|
|
|
+ CoreData core = getCoreData();
|
|
|
+
|
|
|
+ DefaultMutableTreeNode node = core.getNodeByPk(pk_doc);
|
|
|
+
|
|
|
+ // pk_doc找到对应数据而且(pk_org的数据已经在缓存中 或者 之前已经尝试加载过pk_org或其等价组织的数据)
|
|
|
+ if (node != null
|
|
|
+ && (core.isOrgCached(pk_org) || loadedOrg
|
|
|
+ .contains(getVisibleUitl().getEquivalentPkOrg(beanid,
|
|
|
+ pk_org)))) {
|
|
|
+ return node;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // 原因有三
|
|
|
+ // 1.查询了未缓存的组织的数据
|
|
|
+ // 2.版本过期,有新增数据
|
|
|
+ // 3.错误的pk
|
|
|
+ synchronized (this) {
|
|
|
+ node = core.getNodeByPk(pk_doc);
|
|
|
+
|
|
|
+ if (node == null) {
|
|
|
+ loadDatasByPkOrg(pk_org);
|
|
|
+ // 很重要,必须重新获取core
|
|
|
+ core = getCoreData();
|
|
|
+ node = core.getNodeByPk(pk_doc);
|
|
|
+ // if(node==null) 我们需要黑名单
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<IBDData> getChildDocs(String pk_org, String pk_doc,
|
|
|
+ boolean isIncludeSelf) {
|
|
|
+
|
|
|
+ DefaultMutableTreeNode node = findNodeByPkLoadDataIfNecessary(pk_org,
|
|
|
+ pk_doc);
|
|
|
+
|
|
|
+ if (node == null)
|
|
|
+ return new ArrayList<IBDData>();
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Enumeration<DefaultMutableTreeNode> e = node.preorderEnumeration();
|
|
|
+ // 排除自身
|
|
|
+ e.nextElement();
|
|
|
+
|
|
|
+ List<IBDData> datas = new ArrayList<IBDData>();
|
|
|
+ if (isIncludeSelf) {
|
|
|
+ datas.add((IBDData) node.getUserObject());
|
|
|
+ }
|
|
|
+ while (e.hasMoreElements()) {
|
|
|
+ DefaultMutableTreeNode tempNode = (DefaultMutableTreeNode) e
|
|
|
+ .nextElement();
|
|
|
+ datas.add((IBDData) tempNode.getUserObject());
|
|
|
+
|
|
|
+ }
|
|
|
+ datas = getVisibleUitl()
|
|
|
+ .filterDataByVisibleScope(datas, pk_org, beanid);
|
|
|
+
|
|
|
+ return clone(datas);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getClassTypeID() {
|
|
|
+ return this.beanid;
|
|
|
+ }
|
|
|
+
|
|
|
+ CoreData getCoreData() {
|
|
|
+ // 加读锁
|
|
|
+ rwlock.readLock().lock();
|
|
|
+ try {
|
|
|
+ CoreData result = coreData;
|
|
|
+ return result;
|
|
|
+ } finally {
|
|
|
+ rwlock.readLock().unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private Map<String, CoreData> getCoreDataCacheMap() {
|
|
|
+ if (coreDataCacheMap == null) {
|
|
|
+ String regionName = ACCESSOR_REGIONNAME_PREFIX + this.beanid;
|
|
|
+ ICache cache = BDCacheFactory.getCacheWithFileStratery(regionName);
|
|
|
+ coreDataCacheMap = cache.toMap();
|
|
|
+ }
|
|
|
+ return coreDataCacheMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IBDData getDocByCode(String pk_org, String docCode) {
|
|
|
+ IBDData[] data = getDocByCodes(pk_org, new String[] { docCode });
|
|
|
+ if (data != null && data.length > 0)
|
|
|
+ return data[0];
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<IBDData> getDocByCodeInCache(List<IBDData> cacheData, String code) {
|
|
|
+ List<IBDData> dataList = new ArrayList<IBDData>();
|
|
|
+ if (cacheData == null || cacheData.size() == 0
|
|
|
+ || StringUtils.isEmpty(code))
|
|
|
+ return null;
|
|
|
+ for (IBDData datum : cacheData) {
|
|
|
+ if (code.equals(datum.getCode()))
|
|
|
+ dataList.add(clone(datum));
|
|
|
+// return clone(datum);
|
|
|
+ }
|
|
|
+ return dataList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IBDData[] getDocByCodes(String pk_org, String[] docCodes) {
|
|
|
+ if (StringUtils.isEmpty(pk_org) || docCodes == null
|
|
|
+ || docCodes.length == 0)
|
|
|
+ return new IBDData[0];
|
|
|
+ List<IBDData> result = new ArrayList<IBDData>();
|
|
|
+ if (!loadedOrg.contains(getVisibleUitl().getEquivalentPkOrg(beanid,
|
|
|
+ pk_org))) {
|
|
|
+ loadDatasByPkOrg(pk_org);
|
|
|
+ }
|
|
|
+ CoreData core = getCoreData();
|
|
|
+ // 本组织可见的已缓存数据
|
|
|
+// List<IBDData> cacheData = getVisibleUitl().filterDataByVisibleScope(
|
|
|
+// core.extractDatas(), pk_org, this.beanid);
|
|
|
+// for (int i = 0; i < result.length; i++) {
|
|
|
+// result[i] = getDocByCodeInCache(cacheData, docCodes[i]);
|
|
|
+// }
|
|
|
+ List<IBDData> coredata = core.extractDatas();
|
|
|
+
|
|
|
+ List<IBDData> cacheData = getVisibleUitl().filterDataByVisibleScope(core.extractDatas(), pk_org, this.beanid);
|
|
|
+
|
|
|
+ for (int i = 0; i < docCodes.length; i++) {
|
|
|
+ List<IBDData> bdDatas = getDocByCodeInCache(cacheData, docCodes[i]);
|
|
|
+ if(bdDatas == null || bdDatas.size() == 0){
|
|
|
+ result.add(null);
|
|
|
+ }else{
|
|
|
+ result.addAll(bdDatas);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ // 本组织可见的已缓存数据
|
|
|
+// result = getVisibleUitl().filterDataByVisibleScope(
|
|
|
+// result, pk_org, this.beanid);
|
|
|
+ return result.toArray(new IBDData[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IBDData[] getDocByNamesWithMainLang(String pk_org, String[] docNames) {
|
|
|
+ if (StringUtils.isEmpty(pk_org) || docNames == null
|
|
|
+ || docNames.length == 0)
|
|
|
+ return new IBDData[0];
|
|
|
+ IBDData[] result = new IBDData[docNames.length];
|
|
|
+ if (!loadedOrg.contains(getVisibleUitl().getEquivalentPkOrg(beanid,
|
|
|
+ pk_org))) {
|
|
|
+ loadDatasByPkOrg(pk_org);
|
|
|
+ }
|
|
|
+ CoreData core = getCoreData();
|
|
|
+ // 本组织可见的已缓存数据
|
|
|
+ List<IBDData> cacheData = getVisibleUitl().filterDataByVisibleScope(
|
|
|
+ core.extractDatas(), pk_org, this.beanid);
|
|
|
+ for (int i = 0; i < result.length; i++) {
|
|
|
+ result[i] = getDocByNameWithMainLanguageInCache(cacheData,
|
|
|
+ docNames[i]);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IBDData getDocByNameWithMainLang(String pk_org, String docName) {
|
|
|
+ IBDData[] data = getDocByNamesWithMainLang(pk_org,
|
|
|
+ new String[] { docName });
|
|
|
+ if (data != null && data.length > 0)
|
|
|
+ return data[0];
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private IBDData getDocByNameWithMainLanguageInCache(
|
|
|
+ List<IBDData> cacheData, String name) {
|
|
|
+ if (cacheData == null || cacheData.size() == 0
|
|
|
+ || StringUtils.isEmpty(name))
|
|
|
+ return null;
|
|
|
+ for (IBDData datum : cacheData) {
|
|
|
+ if (name.equals(datum.getName().getText()))
|
|
|
+ return clone(datum);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IBDData getDocByPk(String docPk) {
|
|
|
+ // 先从树上找,没有就委托给generalAccessor
|
|
|
+ IBDData result = getIBDDataFromTree(docPk);
|
|
|
+
|
|
|
+ if (result == null) {
|
|
|
+ result = generalAccesor.getDocByPk(docPk);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IBDData[] getDocbyPks(String[] docPks) {
|
|
|
+ if (docPks == null)
|
|
|
+ return new IBDData[0];
|
|
|
+ LinkedHashMap<String, IBDData> pk_doc_map = new LinkedHashMap<String, IBDData>();
|
|
|
+ List<String> notMatchPKs = new ArrayList<String>();
|
|
|
+ IBDData[] resultsFromTree = getIBDDatasFromTree(docPks);
|
|
|
+
|
|
|
+ for (int i = 0; i < docPks.length; i++) {
|
|
|
+ String pk = docPks[i];
|
|
|
+ IBDData data = resultsFromTree[i];
|
|
|
+ pk_doc_map.put(pk, data);
|
|
|
+ if (data == null) {
|
|
|
+ notMatchPKs.add(pk);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ IBDData[] resultFromGA = generalAccesor.getDocbyPks(notMatchPKs
|
|
|
+ .toArray(new String[0]));
|
|
|
+
|
|
|
+ if (resultFromGA != null) {
|
|
|
+ for (IBDData data : resultFromGA) {
|
|
|
+ if (data != null) {
|
|
|
+ pk_doc_map.put(data.getPk(), data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IBDData[] data = new IBDData[docPks.length];
|
|
|
+ for (int i = 0; i < docPks.length; i++) {
|
|
|
+ data[i] = clone(pk_doc_map.get(docPks[i]));
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<IBDData> getFatherDocs(String pk_org, String pk_doc,
|
|
|
+ boolean isIncludeSelf) {
|
|
|
+ DefaultMutableTreeNode node = findNodeByPkLoadDataIfNecessary(pk_org,
|
|
|
+ pk_doc);
|
|
|
+ if (node == null)
|
|
|
+ return new ArrayList<IBDData>();
|
|
|
+
|
|
|
+ List<IBDData> datas = new ArrayList<IBDData>();
|
|
|
+ TreeNode[] path = node.getPath();
|
|
|
+ for (int i = path.length - 1; i >= 0; i--) {
|
|
|
+ DefaultMutableTreeNode obj = (DefaultMutableTreeNode) path[i];
|
|
|
+ if (obj != null && obj.getUserObject() != null
|
|
|
+ && obj.getUserObject() instanceof IBDData) {
|
|
|
+ if (path[i] != node) {
|
|
|
+ datas.add((IBDData) obj.getUserObject());
|
|
|
+ } else if (isIncludeSelf) {
|
|
|
+ datas.add((IBDData) obj.getUserObject());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return clone(datas);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<IBDData> getFirstLevelDocs(String pk_org) {
|
|
|
+
|
|
|
+ if (!loadedOrg.contains(getVisibleUitl().getEquivalentPkOrg(beanid,
|
|
|
+ pk_org))) {
|
|
|
+ loadDatasByPkOrg(pk_org);
|
|
|
+ }
|
|
|
+ List<IBDData> dataList = new ArrayList<IBDData>();
|
|
|
+ CoreData core = getCoreData();
|
|
|
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) core.getModel()
|
|
|
+ .getRoot();
|
|
|
+ int childCount = root.getChildCount();
|
|
|
+ for (int i = 0; i < childCount; i++) {
|
|
|
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode) root
|
|
|
+ .getChildAt(i);
|
|
|
+ if (node != null && node.getUserObject() != null
|
|
|
+ && node.getUserObject() instanceof IBDData) {
|
|
|
+ dataList.add((IBDData) node.getUserObject());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return clone(getVisibleUitl().filterDataByVisibleScope(dataList,
|
|
|
+ pk_org, beanid));
|
|
|
+ }
|
|
|
+
|
|
|
+ private IBDData getIBDDataFromTree(String docPk) {
|
|
|
+ IBDData[] datas = getIBDDatasFromTree(new String[] { docPk });
|
|
|
+ return datas[0];
|
|
|
+ }
|
|
|
+
|
|
|
+ private IBDData[] getIBDDatasFromTree(String[] docPks) {
|
|
|
+ CoreData cd = getCoreData();
|
|
|
+ IBDData[] results = new IBDData[docPks.length];
|
|
|
+ for (int i = 0; i < docPks.length; i++) {
|
|
|
+ String docPk = docPks[i];
|
|
|
+ DefaultMutableTreeNode node = cd.getNodeByPk(docPk);
|
|
|
+ IBDData result = null;
|
|
|
+ if (node != null) {
|
|
|
+ result = ((IBDData) node.getUserObject());
|
|
|
+ }
|
|
|
+ results[i] = clone(result);
|
|
|
+ }
|
|
|
+ return results;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IAccessorQueryService getQueryService() {
|
|
|
+ return this.queryService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IAccessorVisibleUtil getVisibleUitl() {
|
|
|
+ return this.visibleUitl;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initCoreData() {
|
|
|
+ String dsName = BDCacheMiscUtil.getCurrentDatasourceName();
|
|
|
+ this.coreData = getCoreDataCacheMap().get(dsName + COREDATA_CACHE_KEY);
|
|
|
+ if (this.coreData == null) {
|
|
|
+ setCoreData(new CoreData(new ArrayList<IBDData>(), ""));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isHaslevel() {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isLeaf(String pk_org, String pk_doc) {
|
|
|
+// DefaultMutableTreeNode node = findNodeByPkLoadDataIfNecessary(pk_org,
|
|
|
+// pk_doc);
|
|
|
+// if (node != null)
|
|
|
+// return node.isLeaf();
|
|
|
+// return false;
|
|
|
+ List<IBDData> children = this.getChildDocs(pk_org, pk_doc, false);
|
|
|
+ return CollectionUtils.isEmpty(children);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据管控模式中指定的可见性加载,从pk_org角度所能看到的数据。
|
|
|
+ *
|
|
|
+ * @param pk_org
|
|
|
+ * @throws BusinessException
|
|
|
+ */
|
|
|
+ // TODO: 没有定义管控模式,怎么处理?
|
|
|
+ // TODO: 当组织能看到集团的数据, 加载不同组织时,需要避免重复加载集团数据
|
|
|
+ // TODO: 加载数据出来后要放到treemodel里去
|
|
|
+ protected synchronized void loadDatasByPkOrg(String pk_org) {
|
|
|
+
|
|
|
+ // 把pk_org根据可见性转换成更高等级的pk_org
|
|
|
+
|
|
|
+ pk_org = getVisibleUitl().getEquivalentPkOrg(beanid, pk_org);
|
|
|
+
|
|
|
+ HierachicalDataCacheLoadingResult result = getQueryService()
|
|
|
+ .loadDatasByPkOrgFromBD(pk_org, beanid,
|
|
|
+ getCoreData() == null ? "" : getCoreData().getVersion());
|
|
|
+
|
|
|
+ List<IBDData> datas = result.getDatas();
|
|
|
+
|
|
|
+ if (datas.size() > 0) {
|
|
|
+
|
|
|
+ boolean outOfData = !StringUtils.equals(getCoreData().getVersion(),
|
|
|
+ result.getNewVersion());
|
|
|
+
|
|
|
+ if (outOfData) {
|
|
|
+ // sortDatas((ArrayList<IBDData>) datas);
|
|
|
+ setCoreData(new CoreData(datas, result.getNewVersion()));
|
|
|
+ loadedOrg.clear();
|
|
|
+ } else {
|
|
|
+ List<IBDData> datasInCache = getCoreData().extractDatas();
|
|
|
+ ArrayList<IBDData> combinedDatas = combineDatas(datasInCache,
|
|
|
+ datas);
|
|
|
+ // sortDatas(combinedDatas);
|
|
|
+ setCoreData(new CoreData(combinedDatas, result.getNewVersion()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ loadedOrg.add(pk_org);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ void setBeanid(String beanid) {
|
|
|
+ this.beanid = beanid;
|
|
|
+ generalAccesor = new GeneralAccessor(beanid);
|
|
|
+ initCoreData();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setCoreData(CoreData coreData) {
|
|
|
+ rwlock.writeLock().lock();
|
|
|
+ try {
|
|
|
+ this.coreData = coreData;
|
|
|
+ String dsName = BDCacheMiscUtil.getCurrentDatasourceName();
|
|
|
+ getCoreDataCacheMap().put(dsName + COREDATA_CACHE_KEY, this.coreData);
|
|
|
+ } finally {
|
|
|
+ rwlock.writeLock().unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setQueryService(IAccessorQueryService service) {
|
|
|
+ this.queryService = service;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setVisibleUitl(IAccessorVisibleUtil visibleUitl) {
|
|
|
+ this.visibleUitl = visibleUitl;
|
|
|
+ }
|
|
|
+}
|