`
p2p2500
  • 浏览: 11515 次
  • 性别: Icon_minigender_2
  • 来自: 南京
社区版块
存档分类
最新评论

NC业务插件模型源码分析

 
阅读更多

 

NC业务插件模型源码分析

1. Summary

为了增加NC程序事件响应的可扩展性,在Java事件响应的前后添加一些必要的操作。

2. NC事件监听器数据库设计

数据库表设计

表中字段的含义如下表:

pub_eventlistener

字段 含义 举例
pk_eventlistener 主键 1001ZF1000000000099E
name 名称 同步经销商云平台商家
implcalssname 实现类的全限定名,需实现IBusinessListener接口 OrgInsertAfterListener
pk_eventtype 外键,连接pub_eventtype表 1018Z01000000000LLB9
owner 外键,连接dap_dapsystem EC99

pub_eventtype

字段 含义 举例
pk_eventtype 主键 1018Z01000000000LLB9
eventtypename 事件类型名称 新增后
sourceid 元数据ID 945f38b6-48ec-43e6-bb09-77ec89a3728f
owner ? 1010

dap_dapsystem

字段 含义 举例
moduleid 主键,与pub_eventlistener表的owner关联 EC99
devmodule 模块名称 eschain

3 基本代码分析

3.1 代码配置组合

为了说明业务插件代码的运行原理,我们以品牌(bd_branddoc)插入后业务插件为例进行说明。VC6.0中大部分单据界面都需要一个Spring.xml 文件来配置界面,对界面进行布局。这个xml文件必须放在client文件夹下,路径和注册功能节点是注册的“BeanConfigPath”参数一致。

应用管理平台->开发配置工具->功能注册

uiuapbd_brand.jar文件中找到对应的spring配置文件:branddoc_globe.xml,主要配置如下:

<beans>
    <!--
        界面布局总装###########################################################
    -->
    <bean id="container" class="nc.ui.uif2.TangramContainer"
        init-method="initUI">
        <property name="tangramLayoutRoot">
            <bean class="nc.ui.uif2.tangramlayout.node.CNode">
                <property name="component" ref="brandlist"></property>
            </bean>
        </property>
        <property name="editActions">
            <list>
                <ref bean="saveAction" />
                ......
            </list>
        </property>
        <property name="model" ref="batchBillTableModel"></property>
    </bean>

    <bean id="saveAction" class="nc.ui.uif2.actions.batch.BatchSaveAction">
        <property name="model" ref="batchBillTableModel" />
        <property name="editor" ref="brandlist" />
        <property name="validationService" ref="validatorServicer"></property>
    </bean>

    <!-- 批量操作应用模型 -->
    <bean id="batchBillTableModel" class="nc.ui.uif2.model.BatchBillTableModel">
        <property name="service" ref="batchModelService"></property>
        <property name="businessObjectAdapterFactory" ref="objectadapterfactory"></property>
        <property name="context" ref="context"></property>
    </bean>

    <!-- 应用服务类,负责进行模型操作的处理 -->
    <bean id="batchModelService" class="nc.ui.bd.material.branddoc.model.BrandDocModelServicer" />
    ......
</beans>

 

3.2 代码调用过程

当点击保存按钮时,会调用nc.ui.uif2.actions.batch.BatchSaveAction类(父类为:javax.swing.Action)的doAction方法。基本的类调用关系如下图:

品牌业务插件调用过程

nc.ui.uif2.actions.batch.BatchSaveAction#doAction()
↓
nc.ui.uif2.model.BatchBillTableModel#save()
↓
nc.ui.bd.material.branddoc.model.BrandDocModelServicer#batchSave
↓
nc.impl.bd.material.branddoc.BrandDocManagerImpl#batchSaveBrandDoc
↓
nc.impl.bd.material.branddoc.BrandDocManagerImpl(父类:nc.bs.bd.baseservice.md.BatchBaseService)#batchSave
↓
insertVO
↓
fireBeforeInsertEvent
fireAfterInsertEvent
↓
nc.bs.businessevent.bd.BDCommonEventUtil#dispatchInsertBeforeEvent
nc.bs.businessevent.bd.BDCommonEventUtil#dispatchInsertAfterEvent
↓
nc.bs.businessevent.EventDispatcher#fireEvent() // 静态方法

3.4 EventDispatcher事件派发过程

业务插件的事件派发过程主要有nc.bs.businessevent.EventDispatcher类的静态方法fireEvent完成,核心代码如下:

public static void fireEvent(IBusinessEvent event) throws BusinessException {

        writeDebugLog(event);
        // 从数据库中获取event listener 数据映射关系
        Map<String, UnionVO> classNameMap = getListenersInfo(event.getSourceID(), event.getEventType());
        if (classNameMap == null || classNameMap.isEmpty())
            return;

        String className = null, devModuleCode = null;
        try {
            String currgroup_localtype = getCurrGroupLocalType();
            String currgroup_industrytype = getCurrGroupIndustryType();

            for (Iterator<String> iter = classNameMap.keySet().iterator(); iter
                    .hasNext();) {
              // 获取event listener 的实现类名称
                className = iter.next();
                UnionVO unionvo = classNameMap.get(className);
                devModuleCode = unionvo.getDevmodulecode();
                String classInfoMsg = "Plugin class [" + className + "] modulecode [" + devModuleCode + "] ";
                /*
                 * 执行优先级为1/2/3/4的插件并集: 
                 * 行业为水平+本地化为国际化
                 * 行业为水平+ 本地化(如果本地化能匹配)
                 * 匹配行业(如果行业能匹配)+ 本地化为国际化 
                 * 匹配行业(如果行业匹配) + 本地化(如果本地化能匹配)
                 * 
                 * 插件中,行业为空或者为默认值综合控股集团按水平算,本地化为空或为中国按国际化算
                 */
                String localtype = StringUtil.isEmpty(unionvo.getLocaltype()) ? "" : unionvo.getLocaltype();
                String industrytype = StringUtil.isEmpty(unionvo.getIndustrytype()) ? "" : unionvo.getIndustrytype();
                int level = LocalAndIndustryLevelQueryUtil.getLevelByLocalAndIndustry(
                        localtype, industrytype, currgroup_localtype, currgroup_industrytype);
                if (level == 1 || level == 2 || level == 3 || level == 4) {
                    Logger.debug(classInfoMsg + " begin.");
                    Long start = System.currentTimeMillis();
                    // 利用反射获取IBusinessListener实例
                    IBusinessListener instance = getInstanceByClassName(className, devModuleCode);
                  // 执行Event listener 的doAction方法
                    instance.doAction(event);
                    Logger.debug(classInfoMsg + " end successfully.cost time : " + (System.currentTimeMillis() - start));
                }
            }
        } catch (BusinessException e) {
            Logger.error(getErrorMsg(event, className), e);
            throw e;
        } catch (RuntimeException e) {
            Logger.error(getErrorMsg(event, className), e);
            throw e;
        }
    }

 

fireEvent方法的主要任务是说先从表:pub_eventlistener,pub_eventtype与dap_dapsystem获取相应的数据并保存到Map中

nc.bs.businessevent.EventDispatcher#getListenersInfo() // 返回值:Map<String, UnionVO>
↓
getEventType_ClassNameMap() // 返回值为: Map<String, Map<String, UnionVO>>
↓
getAllListenersMap() 
↓
getAllListenersByOrder()
↓
nc.impl.businessevent.EventListenerQryServiceImpl#getAllListeners()

//getAllListeners的代码实现如下:
public UnionVO[] getAllListeners() throws BusinessException {
        String sql = "select T1.sourceid as sourceid,T1.eventtypecode as eventtype," +
                    "T0.implclassname as implclassname,T0.operindex as operindex," +
                    "M.devmodule as devmodulecode," +
                    "T0.localtype as localtype,T0.industrytype as industrytype " +
                     "from pub_eventlistener T0 " +
                        "left outer join pub_eventtype T1 on T0.pk_eventtype =T1.pk_eventtype " +
                        "left join dap_dapsystem  M on M.moduleid=T0.owner "+
                     "where T0.enabled = 'Y' or T0.enabled = 'y'";
        List<UnionVO> vos = (List<UnionVO>) getBaseDAO().executeQuery(sql,
                new BeanListProcessor(UnionVO.class));
        return vos.toArray(new UnionVO[0]);
    }
  

getEventType_ClassNameMap返回Map>的映射关系,他们的含义如下:

  含义 举例
Key SourceId+'@'+eventtytpe 3ee53558-6398-4096-a91f-c7aa00e93701@新增后
Value implclassname与UnionVo的映射  

其中SourceId的获取是在nc.impl.bd.material.branddoc.BrandDocManagerImpl实例创建时指定的:

 public BrandDocManagerImpl() {
        super(IBDMetaDataIDConst.BRANDDOC);
    }

 

nc.itf.bd.pub.IBDMetaDataIDConst中包含了所有模块对应的SourceId常量值。

以上。

分享到:
评论

相关推荐

    iuap studio for ncc v3.5使用指南.docx

    - **创建NCC项目与组件**: 创建新的NCC项目,并定义所需的组件,这些组件可以是业务逻辑、数据模型或者用户界面元素。 - **设计元数据**: 元数据是描述应用结构和行为的关键,开发者通过设计元数据来定义数据结构...

    mexcdf.R14sp1-2.r2811.zip_matlab r14 mexnc_mexcdf

    在实际应用中,使用mexcdf和mexnc可以极大地方便科研人员对NetCDF数据进行分析和处理,比如读取气候模型的输出、进行数据可视化,或者构建基于NetCDF的算法和应用程序。由于这些插件是针对较旧的MATLAB版本,对于...

    Maven权威指南 很精典的学习教程,比ANT更好用

    Creative Commons BY-ND-NC Foreword: Beta 0.16 Preface 1. How to Use this Book 2. Your Feedback 3. Font Conventions 4. Maven Writing Conventions 5. Acknowledgements 1. 介绍 Apache Maven 1.1....

    VC与Labview、Matlab编程论文资料[2].rar

    基于VC_的NC代码自动生成程序开发.pdf 基于VC_的OpenGL三维图形开发设计.pdf 基于VC_的PC机与PLC串口通讯的实现.pdf 基于VC_的UG二次开发技术UG_OpenMenuScript的应用.pdf 基于VC_的Word文档自动生成技术.pdf 基于VC...

    VC与Labview、Matlab编程论文资料

    基于VC_的NC代码自动生成程序开发.pdf 基于VC_的OpenGL三维图形开发设计.pdf 基于VC_的PC机与PLC串口通讯的实现.pdf 基于VC_的UG二次开发技术UG_OpenMenuScript的应用.pdf 基于VC_的Word文档自动生成技术.pdf 基于VC...

    VC与Labview、Matlab编程论文资料[4].rar

    基于VC_的NC代码自动生成程序开发.pdf 基于VC_的OpenGL三维图形开发设计.pdf 基于VC_的PC机与PLC串口通讯的实现.pdf 基于VC_的UG二次开发技术UG_OpenMenuScript的应用.pdf 基于VC_的Word文档自动生成技术.pdf 基于VC...

Global site tag (gtag.js) - Google Analytics