public class ModelReader implements Serializable {
public static final String module = ModelReader.class.getName();
private static final UtilCache<String, ModelReader> readers = UtilCache.createUtilCache("entity.ModelReader", 0, 0);
protected Map<String, ModelEntity> entityCache = null;
protected int numEntities = 0;
protected int numViewEntities = 0;
protected int numFields = 0;
protected int numRelations = 0;
protected int numAutoRelations = 0;
protected String modelName;
/**實體資源句柄文件集合*/
protected Collection<ResourceHandler> entityResourceHandlers;
/**實體資源句柄文件爲key,其下面entityName的集合爲v*/
protected Map<ResourceHandler, Collection<String>> resourceHandlerEntities;
/**entityName爲k 實體資源句柄文件 爲v*/
protected Map<String, ResourceHandler> entityResourceHandlerMap;
/**
* @author 鄭小康
*
* 1.根據delegatorName獲取對應DelegatorElement標籤實例
*
* 2.獲取Delegator的entity-model-reader屬性值
*
* 3.根據entity-model-reader屬性值獲取ModelReader實例
*
* 4.如果ModelReader實例爲空,則創建其對應的ModelReader,並獲取所有實體緩存
*
* 5.以entity-model-reader屬性值爲k ModelReader實例爲v存放到readers這個UtilCache中去
*
* 6.返回當前ModelReader實例
* */
public static ModelReader getModelReader(String delegatorName) throws GenericEntityException {
DelegatorElement delegatorInfo = EntityConfig.getInstance().getDelegator(delegatorName);
if (delegatorInfo == null) {
throw new GenericEntityConfException("Could not find a delegator with the name " + delegatorName);
}
String tempModelName = delegatorInfo.getEntityModelReader();
ModelReader reader = readers.get(tempModelName);
if (reader == null) {
reader = new ModelReader(tempModelName);
// preload caches...
reader.getEntityCache();
reader = readers.putIfAbsentAndGet(tempModelName, reader);
}
return reader;
}
/**
* @author 鄭小康
*
* 1.賦值entity-model-reader的屬性
*
* 2.根據entity-model-reader的屬性值獲取其對應的EntityModelReader實例,如果爲空就拋出異常
* 原因:其獲取的是EntityConfig實例的中的屬性,EntityModelReader是在EntityConfig實例化是加載的屬性標籤的對象,所以沒有是肯定有問題的
*
* 3.添加entityngine.xml中的句柄屬性標籤MainResourceHandler實例
*
* 4.獲取*****-component.xml文件中entity-resource標籤類型爲model,根據與entity-model-reader的屬性值對應reader-name構建ComponentResourceHandler實例添加到entityModelResourceHandlers這個集合
*
* 注意:這個構造器主要是給entityResourceHandlers這個集合中添加了當前EntityModelReader 對應entity-resource對應的實例
* 它是一個私有構造器,通過getModelReader方法來創建對應實例,後續操作在getModelReader這個靜態方法中
* */
private ModelReader(String modelName) throws GenericEntityException {
this.modelName = modelName;
entityResourceHandlers = new LinkedList<ResourceHandler>();
resourceHandlerEntities = new HashMap<ResourceHandler, Collection<String>>();
entityResourceHandlerMap = new HashMap<String, ResourceHandler>();
EntityModelReader entityModelReaderInfo = EntityConfig.getInstance().getEntityModelReader(modelName);
if (entityModelReaderInfo == null) {
throw new GenericEntityConfException("Cound not find an entity-model-reader with the name " + modelName);
}
// get all of the main resource model stuff, ie specified in the entityengine.xml file
for (Resource resourceElement : entityModelReaderInfo.getResourceList()) {
ResourceHandler handler = new MainResourceHandler(EntityConfig.ENTITY_ENGINE_XML_FILENAME, resourceElement.getLoader(), resourceElement.getLocation());
entityResourceHandlers.add(handler);
}
// get all of the component resource model stuff, ie specified in each fadp-component.xml file
for (ComponentConfig.EntityResourceInfo componentResourceInfo: ComponentConfig.getAllEntityResourceInfos("model")) {
if (modelName.equals(componentResourceInfo.readerName)) {
entityResourceHandlers.add(componentResourceInfo.createResourceHandler());
}
}
}
/**
* @author 鄭小康
* 1.判斷節點元素是否是entity
*
* 2.獲取entity-name的值
*
* 3.獲取entity的redefinition屬性,這個屬性的作用是說明這個實體不能被覆蓋,即entity節點元素不能定義兩遍
* 但這僅僅是一個警告,定義了後面的就會覆蓋錢買呢
*
* 4.獲取當前資源句柄文件的實體名集合,爲空則實例化一個LinkedList集合
* 將當前實體名添加到集合
*
* 5.以entityName爲k entityResourceHandler爲v存放在entityResourceHandlerMap,這樣做的好處是根據entityName獲取其資源句柄文件
*
* 6.實體不爲空,構造對應的modelEntity或者ModelViewEntity
*
* 7.將實體的資源句柄文件路徑添加到當前modelEntity
*
* 8.返回當前modelEntity
*
* 注意:這裏只是構造modelEntity,並沒有在數據庫建表
* */
private ModelEntity buildEntity(ResourceHandler entityResourceHandler, Element curEntityElement, int i, ModelInfo def) throws GenericEntityException {
boolean isEntity = "entity".equals(curEntityElement.getNodeName());
String entityName = UtilXml.checkEmpty(curEntityElement.getAttribute("entity-name")).intern();
//獲取entity的redefinition屬性,這個屬性的作用是
boolean redefinedEntity = "true".equals(curEntityElement.getAttribute("redefinition"));
//獲取當前entityResourceHandler的resourceHandlerEntityNames,裏面存放的是這個句柄文件中存在entity,在這裏獲取的目的是將當前構建的entity的entityName添加進去
Collection<String> resourceHandlerEntityNames = resourceHandlerEntities.get(entityResourceHandler);
if (resourceHandlerEntityNames == null) {
resourceHandlerEntityNames = new LinkedList<String>();
resourceHandlerEntities.put(entityResourceHandler, resourceHandlerEntityNames);
}
resourceHandlerEntityNames.add(entityName);
//檢查緩存中是包含 如果緩存中包含,且它不允許重定義(entity屬性中默認是false) 這樣就會報一些井蓋
if (entityCache.containsKey(entityName) && !redefinedEntity) {
Debug.logWarning("實體 " + entityName + " 被再次定義,其將覆蓋原有的", module);
Debug.logWarning("Entity " + entityName + " 被發現在資源句柄文件 " +
entityResourceHandler + ", 但是已經被定義在 " + entityResourceHandlerMap.get(entityName).toString(), module);
}
//以entityName爲k entityResourceHandler爲v存放在entityResourceHandlerMap,這樣做的好處是根據entityName獲取其資源句柄文件
entityResourceHandlerMap.put(entityName, entityResourceHandler);
//構造對應的modelEntity或者ModelViewEntity
ModelEntity modelEntity = null;
if (isEntity) {
modelEntity = createModelEntity(curEntityElement, null, def);
} else {
modelEntity = createModelViewEntity(curEntityElement, null, def);
}
//獲取句柄資源文件的路徑
String resourceLocation = entityResourceHandler.getLocation();
try {
resourceLocation = entityResourceHandler.getURL().toExternalForm();
} catch (GenericConfigException e) {
Debug.logError(e, "Could not get resource URL", module);
}
//如果modelEntity不爲空,將實體的路徑注入到modelEntity
if (modelEntity != null) {
modelEntity.setLocation(resourceLocation);
// utilTimer.timerString(" After entityCache.put -- " + i + " --");
if (isEntity) {
if (Debug.verboseOn()) Debug.logVerbose("-- [Entity]: #" + i + ": " + entityName, module);
} else {
if (Debug.verboseOn()) Debug.logVerbose("-- [ViewEntity]: #" + i + ": " + entityName, module);
}
} else {
Debug.logWarning("-- -- ENTITYGEN ERROR:getModelEntity: Could not create " +
"entity for entityName: " + entityName, module);
}
return modelEntity;
}
/**
* @author 鄭小康
* 1.檢查entityCache是否爲空,如果不爲空直接返回當前緩存,如果爲空才向下執行
*
* 2.再次檢查,避免其他線程在這個過程創建entityCache
*
* 3.對類屬性進行初始化 numEntities:實體數量 numViewEntities:視圖實體數量 numFields:字段數量
* numRelations: numAutoRelations numAutoRelations:
*
* 4.創建tempViewEntityList<ModelViewEntity>:臨時視圖模型實體集合 tempExtendEntityElementList<Element> 擴展實體元素
*
* 5.遍歷所有資源句柄文件,包括entity-model-reader中孩子標籤Resource 和對應的組件下entity-resource
*
* 6.根據entityResourceHandler的路徑,獲取其對應的文檔的Document實例
*
* 7.從首個節點開始,首先構造ModelInfo,獲取當前entity的屬性
*
* 8.節點有三種 entity view-entity extend-entity
* 如果是實體或者視圖實體,調用buildEntity,構造對應的ModelEntity
* 視圖實體:構造後,添加到tempViewEntityList集合
* 實體:構造後以entityName爲k modelEntity爲v放入到entityCache
*
* 如果是extend-entity,直接將節點元素添加到對應的tempExtendEntityElementList集合
*
* 9.從緩存中獲取extend-entity的name相同的ModelEntity,然後對這個ModelEntity進行擴展字段,並且其會覆蓋原有entity的屬性
*
* 10.將視圖實體添加到對應的成員ModelEntity,這樣就可以通過ModelEntity獲取其下面所有ModelViewEntity
* 並將視圖以entityName爲k ModelViewEntity爲v存放到緩存
*
* 11.檢查出某些視圖存在有些成員實體不存在,列舉出來,這些ModelViewEntity並沒有加到entitycache中
*
* 12構建關係,主要是給當前實體添加其存在的關係集合,關係的實體中也添加這個ModelRelation到CopyOnWriteArrayList<ModelRelation> relations
* CopyOnWrite容器即寫時複製的容器。
* 讀取的時候拷貝一個副本,進行讀取
* 寫入的需要加鎖,對副本進行寫入之後,再將原容器的引用指向新的容器
* 這樣的好處是可以進行併發的讀
*
* */
public Map<String, ModelEntity> getEntityCache() throws GenericEntityException {
if (entityCache == null) { // don't want to block here
synchronized (ModelReader.class) {
// must check if null again as one of the blocked threads can still enter
if (entityCache == null) { // now it's safe
numEntities = 0;
numViewEntities = 0;
numFields = 0;
numRelations = 0;
numAutoRelations = 0;
entityCache = new HashMap<String, ModelEntity>();
List<ModelViewEntity> tempViewEntityList = new LinkedList<ModelViewEntity>();
List<Element> tempExtendEntityElementList = new LinkedList<Element>();
UtilTimer utilTimer = new UtilTimer();
for (ResourceHandler entityResourceHandler: entityResourceHandlers) {
// utilTimer.timerString("Before getDocument in file " + entityFileName);
Document document = null;
try {
document = entityResourceHandler.getDocument();
} catch (GenericConfigException e) {
throw new GenericEntityConfException("Error getting document from resource handler 獲取entitymodel.xml文件失敗", e);
}
if (document == null) {
throw new GenericEntityConfException("Could not get document for " + entityResourceHandler.toString());
}
// utilTimer.timerString("Before getDocumentElement in " + entityResourceHandler.toString());
Element docElement = document.getDocumentElement();
if (docElement == null) {
return null;
}
docElement.normalize();
Node curChild = docElement.getFirstChild();
ModelInfo def = ModelInfo.createFromElements(ModelInfo.DEFAULT, docElement);
int i = 0;
if (curChild != null) {
utilTimer.timerString("Before start of entity loop in " + entityResourceHandler.toString());
do {
boolean isEntity = "entity".equals(curChild.getNodeName());
boolean isViewEntity = "view-entity".equals(curChild.getNodeName());
boolean isExtendEntity = "extend-entity".equals(curChild.getNodeName());
if ((isEntity || isViewEntity) && curChild.getNodeType() == Node.ELEMENT_NODE) {
i++;
ModelEntity modelEntity = buildEntity(entityResourceHandler, (Element) curChild, i, def);
// put the view entity in a list to get ready for the second pass to populate fields...
if (isViewEntity) {
tempViewEntityList.add((ModelViewEntity) modelEntity);
} else {
entityCache.put(modelEntity.getEntityName(), modelEntity);
}
} else if (isExtendEntity && curChild.getNodeType() == Node.ELEMENT_NODE) {
tempExtendEntityElementList.add((Element) curChild);
}
} while ((curChild = curChild.getNextSibling()) != null);
} else {
Debug.logWarning("No child nodes found.", module);
}
utilTimer.timerString("Finished " + entityResourceHandler.toString() + " - Total Entities: " + i + " FINISHED");
}
//從緩存中獲取extend-entity的name相同的ModelEntity,然後對這個ModelEntity進行擴展字段,並且其會覆蓋原有entity的屬性
for (Element extendEntityElement: tempExtendEntityElementList) {
String entityName = UtilXml.checkEmpty(extendEntityElement.getAttribute("entity-name"));
ModelEntity modelEntity = entityCache.get(entityName);
if (modelEntity == null) throw new GenericEntityConfException("Entity to extend does not exist: " + entityName);
modelEntity.addExtendEntity(this, extendEntityElement);
}
//如果視圖不爲空,獲取視圖的大小
while (!tempViewEntityList.isEmpty()) {
int startSize = tempViewEntityList.size();
//對視圖進行迭代
Iterator<ModelViewEntity> mveIt = tempViewEntityList.iterator();
TEMP_VIEW_LOOP:
while (mveIt.hasNext()) {
ModelViewEntity curViewEntity = mveIt.next();
//遍歷當前視圖的所有ModelMemberEntity(member-entity)成員,如果在緩存中不存在就不執行,存在則繼續執行
for (ModelViewEntity.ModelMemberEntity mve: curViewEntity.getAllModelMemberEntities()) {
if (!entityCache.containsKey(mve.getEntityName())) {
continue TEMP_VIEW_LOOP;
}
}
mveIt.remove();
//注入視圖實體所有字段
curViewEntity.populateFields(this);
//加視圖實體添加到其下面所有成員實體ModelEntity下,以爲這可以根據ModelEntity查詢其所有視圖實體
for (ModelViewEntity.ModelMemberEntity mve: curViewEntity.getAllModelMemberEntities()) {
ModelEntity me = entityCache.get(mve.getEntityName());
me.addViewEntity(curViewEntity);
}
entityCache.put(curViewEntity.getEntityName(), curViewEntity);
}
//這段代碼的作用是標識tempViewEntityList集合中的成員是都存在不包含在entityCache
if (tempViewEntityList.size() == startSize) {
// Oops, the remaining views reference other entities
// that can't be found, or they reference other views
// that have some reference problem.
break;
}
}
//這段代碼的作用是在上面遍歷tempViewEntityList,有些MemberEntity在緩存中不存在
//檢查不存在的memberEntity添加到perViewMissingEntities這個SET集合,並將其給輸出
if (!tempViewEntityList.isEmpty()) {
StringBuilder sb = new StringBuilder("View entities reference non-existant members:\n");
Set<String> allViews = new HashSet<String>();
for (ModelViewEntity curViewEntity: tempViewEntityList) {
allViews.add(curViewEntity.getEntityName());
}
for (ModelViewEntity curViewEntity: tempViewEntityList) {
Set<String> perViewMissingEntities = new HashSet<String>();
Iterator<ModelViewEntity.ModelMemberEntity> mmeIt = curViewEntity.getAllModelMemberEntities().iterator();
while (mmeIt.hasNext()) {
ModelViewEntity.ModelMemberEntity mme = mmeIt.next();
String memberEntityName = mme.getEntityName();
if (!entityCache.containsKey(memberEntityName)) {
// this member is not a real entity
// check to see if it is a view
if (!allViews.contains(memberEntityName)) {
// not a view, it's a real missing entity
perViewMissingEntities.add(memberEntityName);
}
}
}
for (String perViewMissingEntity: perViewMissingEntities) {
sb.append("\t[").append(curViewEntity.getEntityName()).append("] missing member entity [").append(perViewMissingEntity).append("]\n");
}
}
throw new GenericEntityConfException(sb.toString());
}
/**
* @author 鄭小康
* 1.遍歷當前ModelReader下所有實體名
* 2.獲取對應ModelEntity
* 3.將其關係進行迭代處理
* 4.如果類型是one 或者one-nofk(不是AutoRelation) 獲取其關係ModelEntity
* 5.將所有key-map的name添加到curEntityKeyFields集合
* 6.實例化ModelRelation
* 7.如果是自關聯,將ModelRealation添加到當前實體
* 如果不是在相關實體加入ModelRealation
* */
TreeSet<String> orderedMessages = new TreeSet<String>();
for (String curEntityName: new TreeSet<String>(this.getEntityNames())) {
ModelEntity curModelEntity = this.getModelEntity(curEntityName);
if (curModelEntity instanceof ModelViewEntity) {
// for view-entities auto-create relationships for all member-entity relationships that have all corresponding fields in the view-entity
} else {
// for entities auto-create many relationships for all type one relationships
// just in case we add a new relation to the same entity, keep in a separate list and add them at the end
List<ModelRelation> newSameEntityRelations = new LinkedList<ModelRelation>();
Iterator<ModelRelation> relationsIter = curModelEntity.getRelationsIterator();
while (relationsIter.hasNext()) {
ModelRelation modelRelation = relationsIter.next();
if (("one".equals(modelRelation.getType()) || "one-nofk".equals(modelRelation.getType())) && !modelRelation.isAutoRelation()) {
ModelEntity relatedEnt = null;
try {
/** 得到參考的 RelEntityName. */
relatedEnt = this.getModelEntity(modelRelation.getRelEntityName());
} catch (GenericModelException e) {
// com.hanlin.fadp.petrescence.datasource.FindMissedEntity.addMissed(modelRelation.getRelEntityName());
throw new GenericModelException("Error getting related entity [" + modelRelation.getRelEntityName() + "] definition from entity [" + curEntityName + "]", e);
}
if (relatedEnt != null) {
// create the new relationship even if one exists so we can show what we are looking for in the info message
// don't do relationship to the same entity, unless title is "Parent", then do a "Child" automatically
String title = modelRelation.getTitle();
if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName()) && "Parent".equals(title)) {
title = "Child";
}
String description = "";
String type = "";
String relEntityName = curModelEntity.getEntityName();
String fkName = "";
ArrayList<ModelKeyMap> keyMaps = new ArrayList<ModelKeyMap>();
boolean isAutoRelation = true;
Set<String> curEntityKeyFields = new HashSet<String>();
for (ModelKeyMap curkm : modelRelation.getKeyMaps()) {
keyMaps.add(new ModelKeyMap(curkm.getRelFieldName(), curkm.getFieldName()));
curEntityKeyFields.add(curkm.getFieldName());
}
keyMaps.trimToSize();
// decide whether it should be one or many by seeing if the key map represents the complete pk of the relEntity
if (curModelEntity.containsAllPkFieldNames(curEntityKeyFields)) {
// always use one-nofk, we don't want auto-fks getting in for these automatic ones
type = "one-nofk";
// to keep it clean, remove any additional keys that aren't part of the PK
List<String> curPkFieldNames = curModelEntity.getPkFieldNames();
Iterator<ModelKeyMap> nrkmIter = keyMaps.iterator();
while (nrkmIter.hasNext()) {
ModelKeyMap nrkm =nrkmIter.next();
String checkField = nrkm.getRelFieldName();
if (!curPkFieldNames.contains(checkField)) {
nrkmIter.remove();
}
}
} else {
type= "many";
}
ModelRelation newRel = ModelRelation.create(relatedEnt, description, type, title, relEntityName, fkName, keyMaps, isAutoRelation);
ModelRelation existingRelation = relatedEnt.getRelation(title + curModelEntity.getEntityName());
if (existingRelation == null) {
numAutoRelations++;
if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName())) {
newSameEntityRelations.add(newRel);
} else {
relatedEnt.addRelation(newRel);
}
} else {
if (newRel.equals(existingRelation)) {
// don't warn if the target title+entity = current title+entity
if (Debug.infoOn() && !(title + curModelEntity.getEntityName()).equals(modelRelation.getTitle() + modelRelation.getRelEntityName())) {
//String errorMsg = "Relation already exists to entity [] with title [" + targetTitle + "],from entity []";
String message = "Entity [" + relatedEnt.getPackageName() + ":" + relatedEnt.getEntityName() + "] already has identical relationship to entity [" +
curModelEntity.getEntityName() + "] title [" + title + "]; would auto-create: type [" +
newRel.getType() + "] and fields [" + newRel.keyMapString(",", "") + "]";
orderedMessages.add(message);
}
} else {
String message = "Existing relationship with the same name, but different specs found from what would be auto-created for Entity [" + relatedEnt.getEntityName() + "] and relationship to entity [" +
curModelEntity.getEntityName() + "] title [" + title + "]; would auto-create: type [" +
newRel.getType() + "] and fields [" + newRel.keyMapString(",", "") + "]";
Debug.logVerbose(message, module);
}
}
} else {
String errorMsg = "Could not find related entity ["
+ modelRelation.getRelEntityName() + "], no reverse relation added.";
Debug.logWarning(errorMsg, module);
}
}
}
if (newSameEntityRelations.size() > 0) {
for (ModelRelation newRel: newSameEntityRelations) {
curModelEntity.addRelation(newRel);
}
}
}
}
if (Debug.infoOn()) {
for (String message : orderedMessages) {
Debug.logInfo(message, module);
}
Debug.logInfo("Finished loading entities; #Entities=" + numEntities + " #ViewEntities=" + numViewEntities + " #Fields=" + numFields + " #Relationships=" + numRelations + " #AutoRelationships=" + numAutoRelations, module);
}
}
}
}
return entityCache;
}
/**
* rebuilds the resourceHandlerEntities Map of Collections based on the current
* entityResourceHandlerMap Map, must be done whenever a manual change is made to the
* entityResourceHandlerMap Map after the initial load to make them consistent again.
*
* Map<ResourceHandler, Collection<String>> resourceHandlerEntities
* Map<String, ResourceHandler> entityResourceHandlerMap
* 依據entityResourceHandlerMap來更新resourceHandlerEntities
* FIXME:暫時不理解爲什麼會出現這種情況
*/
public void rebuildResourceHandlerEntities() {
resourceHandlerEntities = new HashMap<ResourceHandler, Collection<String>>();
Iterator<Map.Entry<String, ResourceHandler>> entityResourceIter = entityResourceHandlerMap.entrySet().iterator();
while (entityResourceIter.hasNext()) {
Map.Entry<String, ResourceHandler> entry = entityResourceIter.next();
// add entityName to appropriate resourceHandlerEntities collection
Collection<String> resourceHandlerEntityNames = resourceHandlerEntities.get(entry.getValue());
if (resourceHandlerEntityNames == null) {
resourceHandlerEntityNames = new LinkedList<String>();
resourceHandlerEntities.put(entry.getValue(), resourceHandlerEntityNames);
}
resourceHandlerEntityNames.add(entry.getKey());
}
}
/**獲取當前模型閱讀器的resourceHandler迭代器*/
public Iterator<ResourceHandler> getResourceHandlerEntitiesKeyIterator() {
if (resourceHandlerEntities == null) return null;
return resourceHandlerEntities.keySet().iterator();
}
public Collection<String> getResourceHandlerEntities(ResourceHandler resourceHandler) {
if (resourceHandlerEntities == null) return null;
return resourceHandlerEntities.get(resourceHandler);
}
public void addEntityToResourceHandler(String entityName, String loaderName, String location) {
entityResourceHandlerMap.put(entityName, new MainResourceHandler(EntityConfig.ENTITY_ENGINE_XML_FILENAME, loaderName, location));
}
public ResourceHandler getEntityResourceHandler(String entityName) {
return entityResourceHandlerMap.get(entityName);
}
/** Gets an Entity object based on a definition from the specified XML Entity descriptor file.
* @param entityName The entityName of the Entity definition to use.
* @return An Entity object describing the specified entity of the specified descriptor file.
*/
public ModelEntity getModelEntity(String entityName) throws GenericEntityException {
if (entityName == null) {
throw new IllegalArgumentException("Tried to find entity definition for a null entityName");
}
Map<String, ModelEntity> ec = getEntityCache();
if (ec == null) {
throw new GenericEntityConfException("ERROR: Unable to load Entity Cache");
}
ModelEntity modelEntity = ec.get(entityName);
if (modelEntity == null) {
String errMsg = "Could not find definition for entity name " + entityName;
// Debug.logError(new Exception("Placeholder"), errMsg, module);
// com.hanlin.fadp.petrescence.datasource.FindMissedEntity.addMissed(entityName);
throw new GenericModelException(errMsg);
}
return modelEntity;
}
public ModelEntity getModelEntityNoCheck(String entityName) {
Map<String, ModelEntity> ec = null;
try {
ec = getEntityCache();
} catch (GenericEntityException e) {
Debug.logError(e, "Error getting entity cache", module);
}
if (ec == null) {
return null;
}
ModelEntity modelEntity = ec.get(entityName);
return modelEntity;
}
/** Creates a Iterator with the entityName of each Entity defined in the specified XML Entity Descriptor file.
* @return A Iterator of entityName Strings
*/
public Iterator<String> getEntityNamesIterator() throws GenericEntityException {
Collection<String> collection = getEntityNames();
if (collection != null) {
return collection.iterator();
} else {
return null;
}
}
/** Creates a Set with the entityName of each Entity defined in the specified XML Entity Descriptor file.
* @return A Set of entityName Strings
*/
public Set<String> getEntityNames() throws GenericEntityException {
Map<String, ModelEntity> ec = getEntityCache();
if (ec == null) {
throw new GenericEntityConfException("ERROR: Unable to load Entity Cache");
}
return ec.keySet();
}
/** Get all entities, organized by package */
public Map<String, TreeSet<String>> getEntitiesByPackage(Set<String> packageFilterSet, Set<String> entityFilterSet) throws GenericEntityException {
Map<String, TreeSet<String>> entitiesByPackage = new HashMap<String, TreeSet<String>>();
//put the entityNames TreeSets in a HashMap by packageName
Iterator<String> ecIter = this.getEntityNames().iterator();
while (ecIter.hasNext()) {
String entityName = ecIter.next();
ModelEntity entity = this.getModelEntity(entityName);
String packageName = entity.getPackageName();
if (UtilValidate.isNotEmpty(packageFilterSet)) {
// does it match any of these?
boolean foundMatch = false;
for (String packageFilter: packageFilterSet) {
if (packageName.contains(packageFilter)) {
foundMatch = true;
}
}
if (!foundMatch) {
//Debug.logInfo("Not including entity " + entityName + " becuase it is not in the package set: " + packageFilterSet, module);
continue;
}
}
if (UtilValidate.isNotEmpty(entityFilterSet) && !entityFilterSet.contains(entityName)) {
//Debug.logInfo("Not including entity " + entityName + " because it is not in the entity set: " + entityFilterSet, module);
continue;
}
TreeSet<String> entities = entitiesByPackage.get(entity.getPackageName());
if (entities == null) {
entities = new TreeSet<String>();
entitiesByPackage.put(entity.getPackageName(), entities);
}
entities.add(entityName);
}
return entitiesByPackage;
}
/** Util method to validate an entity name; if no entity is found with the name,
* characters are stripped from the beginning of the name until a valid entity name is found.
* It is intended to be used to determine the entity name from a relation name.
* @return A valid entityName or null
*/
public String validateEntityName(String entityName) throws GenericEntityException {
if (entityName == null) {
return null;
}
Set<String> allEntities = this.getEntityNames();
while (!allEntities.contains(entityName) && entityName.length() > 0) {
entityName = entityName.substring(1);
}
return (entityName.length() > 0? entityName: null);
}
ModelEntity createModelEntity(Element entityElement, UtilTimer utilTimer, ModelInfo def) {
if (entityElement == null) return null;
this.numEntities++;
ModelEntity entity = new ModelEntity(this, entityElement, utilTimer, def);
return entity;
}
ModelEntity createModelViewEntity(Element entityElement, UtilTimer utilTimer, ModelInfo def) {
if (entityElement == null) return null;
this.numViewEntities++;
ModelViewEntity entity = new ModelViewEntity(this, entityElement, utilTimer, def);
return entity;
}
public ModelRelation createRelation(ModelEntity entity, Element relationElement) {
this.numRelations++;
ModelRelation relation = ModelRelation.create(entity, relationElement, false);
return relation;
}
/**增加當前ModelReader字段個數*/
public void incrementFieldCount(int amount) {
this.numFields += amount;
}
ofbiz實體引擎(四) ModelReader的作用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.