ofbiz中的数据模型

Delegator

Delegator是整个ofbiz中数据库访问的入口,具体实现是GenericDelegator类,在这个类中通过

    protected ModelReader modelReader = null;
    protected ModelGroupReader modelGroupReader = null;

这两个属性变量去查找在xml文件中定义的数据模型

ModelReader

通过ModelReader读取模型实体ModelEntity

 protected Map<String, ModelEntity> entityCache = null;

缓存

   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", 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");
                    }

                    // all entity elements in, now go through extend-entity elements and add their stuff
                    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);
                    }

                    // do a pass on all of the view entities now that all of the entities have
                    // loaded and populate the fields
                    while (!tempViewEntityList.isEmpty()) {
                        int startSize = tempViewEntityList.size();
                        Iterator<ModelViewEntity> mveIt = tempViewEntityList.iterator();
TEMP_VIEW_LOOP:
                        while (mveIt.hasNext()) {
                            ModelViewEntity curViewEntity = mveIt.next();
                            for (ModelViewEntity.ModelMemberEntity mve: curViewEntity.getAllModelMemberEntities()) {
                                if (!entityCache.containsKey(mve.getEntityName())) {
                                    continue TEMP_VIEW_LOOP;
                                }
                            }
                            mveIt.remove();
                            curViewEntity.populateFields(this);
                            for (ModelViewEntity.ModelMemberEntity mve: curViewEntity.getAllModelMemberEntities()) {
                                ModelEntity me = entityCache.get(mve.getEntityName());
                                me.addViewEntity(curViewEntity);
                            }
                            entityCache.put(curViewEntity.getEntityName(), curViewEntity);
                        }
                        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;
                        }
                    }
                    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());
                    }

                    // auto-create relationships
                    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 {
                                        relatedEnt = this.getModelEntity(modelRelation.getRelEntityName());
                                    } catch (GenericModelException e) {
                                        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 - ALL FILES; #Entities=" + numEntities + " #ViewEntities=" + numViewEntities + " #Fields=" + numFields + " #Relationships=" + numRelations + " #AutoRelationships=" + numAutoRelations, module);
                    }
                }
            }
        }
        return entityCache;
    }

从xml配置文件中读取

ModelEntity

模型实体,所有数据库相关的操作都在这里边进行

时间: 2024-10-13 18:43:05

ofbiz中的数据模型的相关文章

ofbiz中的container-1

在ofbiz中,主要有三种container 系统启动时候的container 这个在启动类中被调用,根据framework\base\config\ofbiz-containers.xml中的定义加载其他容器 用来加载组件的container 在这里边定义的container会被顶层container启动,执行指定的class类 这里定义的container执行的时候基本上是组件还没有加载 组件中component-load.xml定义的container 这里边的容器基本上是在组件配置全部加

ofbiz中的实体引擎Delegator

在ofbiz中备受推崇的实体引擎,具体有什么好处由我们向下研究(我也没了解过),先从第一步,实体引擎的创建 在ofbiz中实体引擎是由catalina-container(tomcat容器)中创建的 <container name="catalina-container" loaders="main" class="org.ofbiz.catalina.container.CatalinaContainer">         <

转 OFBiz中services调用机制

OFBiz业务方法里面,当执行一个service的时候,通常采用如下的方式: LocalDispatcher dispatcher = dctx.getDispatcher();     Map<String, Object> result = dispatcher.runSync(getServiceName(), getContext()); LocalDispatcher是本地调度器,实现服务的同步异步调度和定时任务的调度.与服务调度相关的类图如下: LocalDispatcher是一个

OFBiz中services调用机制

OFBiz业务方法里面,当执行一个service的时候,通常采用如下的方式: LocalDispatcher dispatcher = dctx.getDispatcher();     Map<String, Object> result = dispatcher.runSync(getServiceName(), getContext()); LocalDispatcher是本地调度器,实现服务的同步异步调度和定时任务的调度.与服务调度相关的类图如下: LocalDispatcher是一个

ofbiz中的factory模式运用

在ofbiz中大量使用了工厂模式,在使用工厂模式的同时使用了缓存模式,如如下生成数据操作工厂类 /*******************************************************************************  * Licensed to the Apache Software Foundation (ASF) under one  * or more contributor license agreements.  See the NOTICE 

关于在freemarker模板中遍历数据模型List&lt;JavaBean&gt;的经验

本文采用简单的servlet作为后台处理数据的工具,前台使用freemarker的ftl模板作为输出工具,简单说明怎样将封装有实体类对象的List集合注入到ftl模板中并且成功的在遍历显示出来,之前在网上找了很多这方面的资料,但是都没有解决这个问题,所以自己就从头认真的研读的一番freemarker的API文档,阅读了相关的类和接口的功能说明,终于找到了突破口,在这里写出来供和我有相同经历的孩纸(初学者)使用: 首先看我写的domain实体类:News.java public class New

ofbiz中的container-2

当ofbiz启动的时候,他回去查找配置中定义的container并且初始化他们,然后调用初始化方法 public void init(String[] args, String name, String configFile) throws ContainerException; 如果这个方法没有抛出异常的话就会把这个container存放在一个list中(在ContainerLoader类中) private final List<Container> loadedContainers = 

Sahara中的数据模型

声明: 本博客欢迎转载,但请保留原作者信息,并请注明出处! 作者:郭德清 团队:华为杭州OpenStack团队 本文主要是介绍下Sahara中一些常见的数据模型. 1.Config 用于描述配置信息的实体对象. 属性 类型 描述 name string 配置的名称. description string 配置的描述. config_type enum 配置的类型,包括:string.integer.boolean.enum. config_values list 当配置是枚举(enum)类型的时

(转) dedecms中自定义数据模型

刚学习完dedecms的标签语法,我有很多困惑,觉得标签的意义比较抽象,不知道如何用标签来写一些具体的内容.如果有一些数据库的编程经验,就知道一个很常用的编程范例—增删改查.比如说,我要建立的是书本的模型,有索书号,书名,类型……,之后要写一个网页来完成书本信息的增删改查,这篇文章主要解决这种问题. 一频道(内容模型) 我很长时间弄不清频道和栏目的区别.从网上找了一些解释如下: 栏目就是网站中导航划分出的模块,如百度中的新闻.网页.贴吧等就是栏目. 频道是栏目的类型.官方的定义是:频道指内容模型