public class ModelGroupReader implements Serializable {
public static final String module = ModelGroupReader.class.getName();
//緩存所有ModelGroupReader,其k是entity-group-reader屬性值
private static final UtilCache<String, ModelGroupReader> readers = UtilCache.createUtilCache("entity.ModelGroupReader", 0, 0);
private Map<String, String> groupCache = null;//以entityName爲k groupName爲v
private Set<String> groupNames = null;//delegator所有的組名
public String modelName;//entity-group-reader屬性值
public List<ResourceHandler> entityGroupResourceHandlers = new LinkedList<ResourceHandler>();//存放像entity-resource這樣標籤實例
/**
* @author 鄭小康
* 1.獲取當前delegatorName的delegator標籤的DelegatorElement實例
*
* 2.獲取delegator的entity-group-reader屬性值
*
* 3.根據屬性值獲取ModelGroupReader
*
* 4.如果沒有獲取到根據delegatorName和entity-group-reader屬性值構造一個ModelGroupReader實例,具體過程就在本類中
*
* */
public static ModelGroupReader getModelGroupReader(String delegatorName) throws GenericEntityConfException {
DelegatorElement delegatorInfo = EntityConfig.getInstance().getDelegator(delegatorName);
if (delegatorInfo == null) {
throw new GenericEntityConfException("不能發現叫做" + delegatorName+"的delegator");
}
String tempModelName = delegatorInfo.getEntityGroupReader();
ModelGroupReader reader = readers.get(tempModelName);
if (reader == null) {
reader = readers.putIfAbsentAndGet(tempModelName, new ModelGroupReader(delegatorName, tempModelName));
}
return reader;
}
/**
* @author 鄭小康
* 1. 賦值entity-group-reader的屬性值
*
* 2. 根據entity-group-reader的屬性值獲取其對應的EntityGroupReader實例,如果爲空就拋出異常
* 原因:其獲取的是EntityConfig實例的中的屬性,EntityGroupReader是在EntityConfig實例化是加載的屬性標籤的對象,所以沒有是肯定有問題的
*
* 3. 添加entityngine.xml中的句柄屬性標籤MainResourceHandler實例
*
* 4. 獲取component.xml文件中entity-resource標籤類型爲group,根據與entity-group-reader的屬性值對應reader-name構建ComponentResourceHandler實例添加到entityGroupResourceHandlers這個集合
* 作用是通過這個屬性在對應文件中entityName所在的組,後續將其放入到對應的組中,與具體的數據源關聯
*
* 5. 獲取delegator中與entity-group-reader的屬性值對應的entity-resource中reader-name相同的標籤實例
* 根據entity-resource的路徑獲取文件下所有entity-group實例,將其以entityName爲k,groupNam爲v存入到具體的groupCache中
* */
public ModelGroupReader(String delegatorName, String modelName) throws GenericEntityConfException {
this.modelName = modelName;
EntityGroupReader entityGroupReaderInfo = EntityConfig.getInstance().getEntityGroupReader(modelName);
if (entityGroupReaderInfo == null) {
throw new GenericEntityConfException("Cound not find an entity-group-reader with the name " + modelName);
}
for (Resource resourceElement: entityGroupReaderInfo.getResourceList()) {
this.entityGroupResourceHandlers.add(new MainResourceHandler(EntityConfig.ENTITY_ENGINE_XML_FILENAME, resourceElement.getLoader(), resourceElement.getLocation()));
}
// get all of the component resource group stuff, ie specified in each fadp-component.xml file
for (ComponentConfig.EntityResourceInfo componentResourceInfo: ComponentConfig.getAllEntityResourceInfos("group")) {
if (modelName.equals(componentResourceInfo.readerName)) {
this.entityGroupResourceHandlers.add(componentResourceInfo.createResourceHandler());
}
}
// preload caches...
getGroupCache(delegatorName);
}
/**
* @author 鄭小康
* 如果groupCache爲空則將當前delegator下,如果不爲空才進行下面的操作
*
* 1.構建對應的groupCache和groupNames
*
* 2.加載所有資源句柄文件
* 即根據與當前entity-group-reader的屬性值相同的entity-resource中reader-name的entity-resource標籤
* 根據entity-resource的路徑獲取文件下所有entity-group實例,將其以entityName爲k,groupNam爲v存入到具體的groupCache中
* 以entityName爲k groupName爲v 這樣做的作用就是像getEntityGroupName等方法可以根據實體名獲取對應的組名
* */
public Map<String, String> getGroupCache(String delegatorName) {
if (this.groupCache == null) { // don't want to block here
synchronized (ModelGroupReader.class) {
//再次檢查groupCache是否爲空,避免其它線程創建
if (this.groupCache == null) {
//構造groupCache這個hashMap 和groupNames這個TreeSet
this.groupCache = new HashMap<String, String>();
this.groupNames = new TreeSet<String>();
//做一些時間的通知
UtilTimer utilTimer = new UtilTimer();
utilTimer.timerString("[ModelGroupReader.getGroupCache] Before getDocument");
int i = 0;
//遍歷所有entity-resource標籤對應ComponentResourceHandler實例
for (ResourceHandler entityGroupResourceHandler: this.entityGroupResourceHandlers) {
Document document = null;
try {
//解析爲文檔元素
document = entityGroupResourceHandler.getDocument();
} catch (GenericConfigException e) {
Debug.logError(e, "Error loading entity group model", module);
}
//如果document爲空,緩存置爲空,並且返回
if (document == null) {
this.groupCache = null;
return null;
}
// utilTimer.timerString("[ModelGroupReader.getGroupCache] Before getDocumentElement");
Element docElement = document.getDocumentElement();
if (docElement == null) {
continue;
}
//移除空的文本節點
docElement.normalize();
//以獲取首個節點,而後進行遍歷,處理所有entity-group節點將其組名加到groupNames這個集合,並以entityName爲k,groupName爲v存到對應groupCache中
//注意有一個檢查,檢查是否具有entityengine.xml對應的group-map的實例,如果沒有加載就沒有任何意義
Node curChild = docElement.getFirstChild();
if (curChild != null) {
utilTimer.timerString("[ModelGroupReader.getGroupCache] Before start of entity loop");
do {
if (curChild.getNodeType() == Node.ELEMENT_NODE && "entity-group".equals(curChild.getNodeName())) {
Element curEntity = (Element) curChild;
String entityName = UtilXml.checkEmpty(curEntity.getAttribute("entity")).intern();
String groupName = UtilXml.checkEmpty(curEntity.getAttribute("group")).intern();
if (groupName == null || entityName == null) continue;
try {
if (null == EntityConfig.getInstance().getDelegator(delegatorName).getGroupDataSource(groupName)) {
Debug.logError("The declared group name " + groupName + " has no corresponding group-map in entityengine.xml: ", module);
}
} catch (GenericEntityConfException e) {
Debug.logWarning(e, "Exception thrown while getting group name: ", module);
}
this.groupNames.add(groupName);
this.groupCache.put(entityName, groupName);
i++;
}
} while ((curChild = curChild.getNextSibling()) != null);
} else {
Debug.logWarning("[ModelGroupReader.getGroupCache] No child nodes found.", module);
}
}
utilTimer.timerString("[ModelGroupReader.getGroupCache] FINISHED - Total Entity-Groups: " + i + " FINISHED");
}
}
}
return this.groupCache;
}
/**
* @author 鄭小康
* 方法作用:根據entityName和delegatorBaseName獲取其對應的組名
*
* 1.根據方法獲取groupCache
*
* 2.根據entityName獲取組名
*
* 3.如果組名爲空,獲取delegator標籤實體,獲取其默認組名
*
* 4.返回組名
* */
public String getEntityGroupName(String entityName, String delegatorBaseName) {
Map<String, String> gc = getGroupCache(delegatorBaseName);
if (gc != null) {
String groupName = gc.get(entityName);
if (groupName == null) {
DelegatorElement delegatorInfo = null;
try {
delegatorInfo = EntityConfig.getInstance().getDelegator(delegatorBaseName);
} catch (GenericEntityConfException e) {
Debug.logWarning(e, "Exception thrown while getting delegator config: ", module);
}
if (delegatorInfo == null) {
throw new RuntimeException("Could not find DelegatorInfo for delegatorBaseName [" + delegatorBaseName + "]");
}
groupName = delegatorInfo.getDefaultGroupName();
}
return groupName;
} else {
return null;
}
}
/**
* @author 鄭小康
*
* 1.確保delegatorName是默認的delegatorName
*
* 2.調用getGroupCache方法的作用確保將對應的groupCache給加載到類屬性
*
* 3.根據delegator的default-group-name獲取所有其下面默認group-name標籤實例的name,將其添加到一個HashSet集合
*
* 4.向該集合中添加已經通過getGroupCache方法加載的存放過entityName的groupNames集合
* */
public Set<String> getGroupNames(String delegatorBaseName) {
if (delegatorBaseName.indexOf('#') >= 0) {
delegatorBaseName = delegatorBaseName.substring(0, delegatorBaseName.indexOf('#'));
}
getGroupCache(delegatorBaseName);
if (this.groupNames == null) return null;
Set<String> newSet = new HashSet<String>();
try {
newSet.add(EntityConfig.getInstance().getDelegator(delegatorBaseName).getDefaultGroupName());
} catch (GenericEntityConfException e) {
Debug.logWarning(e, "Exception thrown while getting delegator config: ", module);
}
newSet.addAll(this.groupNames);
return newSet;
}
/**
*
* @author 鄭小康
*
* 1.構造一個Set根據delegatorBaseName和groupName,向該set注入該組裏面所有的實體名
*
* 2.遍歷groupCache,將組名相同的entityName添加到enames這個HashSet
*
* 3.返回對應的enames
*/
public Set<String> getEntityNamesByGroup(String delegatorBaseName, String groupName) {
Map<String, String> gc = getGroupCache(delegatorBaseName);
Set<String> enames = new HashSet<String>();
if (groupName == null || groupName.length() <= 0) return enames;
if (UtilValidate.isEmpty(gc)) return enames;
for (Map.Entry<String, String> entry: gc.entrySet()) {
if (groupName.equals(entry.getValue())) enames.add(entry.getKey());
}
return enames;
}
ofbiz實體引擎(五) ModelGroupReader
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.