MDA (Model Driven Architecture) 的核心是模型与基于模型的软件开发。开发者使用
UML 进行建模,在模型中表现系统各方面的重要特征和细节,帮助架构师和开发者获取不同的系统透视图;基于模型的软件开发,要求定义的模型能够驱动软件的设计与实现的过程,在这个过程中,会涉及到不同模型架构的转换,由模型生成业务和数据代码,从而指导视图的生成和变化。本文基于
MDA 的目标,设计和开发程序,通过集成 BIRT 和 EMF 开源组件,实现了从模型驱动业务视图生成的真实场景。
EMF(Eclipse Modeling Framework) 是基于 MOF (Meta Object Facility)
的一个具体的实现工具,是一组结构化模型的 Java 框架和代码生成器,帮助开发者创建、查询、序列化、反序列化和监控模型实例变化。
在一些基于业务、数据分析的项目中,开发者选择使用轻量级的报告设计工具--- Business Intelligence and
Reporting Tools (BIRT),生成丰富直观的分析报告。BIRT 是一组用于 Eclipse 的插件,它允许从数据源(包括关系数据库、XML文件和
Java Object)中抽取数据信息,分析并转换,然后生成各种风格的文档、图表及复杂的分析报告。但是,越来越多的项目,针对自身的程序逻辑、意图把
BIRT 更好融入到代码中,而不是单纯利用 BIRT 的设计工具创建报表。BIRT 具备了良好的扩展机制,为用户提供了集成的空间。
在本文实例中:作者把 EMF 集成到 BIRT 中,指导用户设计 EMF 模型,从模型实例中抽取数据信息,利用 BIRT API
生成报表,实现了模型 -- 代码 -- 视图的创建过程。同时,说明了利用 BIRT 工具创建报表的过程完全可以由程序控制和实现,结果使
BIRT 可以灵活的被集成到用户代码中。
本文的应用程序是在 Eclipse 平台开发的,在阅读本文前,必须对 EMF、BIRT 等插件工具有所了解和应用,能使用 BIRT
Design Report 抽取数据,创建报表。作者设计了一个基于服务报告的应用场景:使用 EMF model 描述业务模型,并生成对应的
API;使用 EMF API 从模型实例中获取数据信息,并进行分析,调用 BIRT Report API生成报表。信息抽取、分析和报表生成的过程,是由程序控制实现的,BIRT
的数据源从传统的关系数据库迁移到 EMF model,验证了 BIRT 对 Java Object 的扩展。下图描述了实现这个服务报告的应用程序的架构:
图1. 基于 EMF 和 BIRT 集成的设计框架
本文的开发和运行环境是基于Microsoft Windows 操作系统。需要安装以下工具和插件:
Eclipse --- 使用Eclipse3.2,JDK使用J2SE1.5。
BIRT --- 使用BIRT2.1.1。
EMF --- 使用EMF2.2.0。
GEF --- 使用GEF3.2。
应用模型设计
作者使用Rational Software Architect (RSA)描述了一个基于服务报告的用例,下图展示了该用例的UML类图设计:
图2. Service Report 的类图设计
将设计的 UML Class Diagram, 生成对应的 serviceReportModel.ecore 文件。并将其导入到
Eclipse 平台中,创建一个 EMF 工程。打开对应的 serviceReportModel.genmodel,生成代码,并运行该插件。
作者根据该 EMF Model 设计了一个"计算员工佣金流程"的服务报告。该业务流程由 5 个活动组成,每个活动调用一个
Service,分别来自于两个服务提供商(Service Vendor)。首先,流程获取所有员工的信息记录,并通过员工的ID计算每个员工的佣金。然后,确认计算结果,并更新员工佣金。最后,发送消息通知员工。下图显示了该业务流程:
图3. 计算员工佣金业务流程
在 Eclipse Runtime 中创建一个基于 Service Report 的 EMF 工程,步骤如下:
1. 创建一个 ServiceReport的model,并选择"Service Report"作为该 model
的根节点。
图4. 创建 Service Report Model
2. 在"Service Report"节点下,创建两个表示 Vendor 的子节点:"EmployeeVendor"和"CRMVendor"。在"EmployeeVendor"节点下,分别创建
3 个 Service:"attainStaffInfoService"、"updateStaffCommisionService"和"notifyStaffService"。在"CRMVendor"节点下,分别创建
2 个 Service:"calculateStaffCommisionService"和"confirmStaffCommisionService"。
图5. 创建 Vendor 和 Service 节点
3. 在"Service Report"节点下,创建 3 个 Process 子节点,并在每个 Process
下创建 5 个 Service Instance,分别引用预先创建好的 5 个 Service。
图6. 设置Service Instance的属性
利用 EMF model 生成的 API,从应用程序中获取模型实例的数据信息。BIRT 通过解析自定义的 Script来调用该应用程序,前提需要将负责解析
EMF model 的相关 jar:
org.eclipse.emf.common_2.2.0.v200606271057.jar
org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar
org.eclipse.emf.ecore_2.2.0.v200606271057.jar
拷贝到:
…\eclipse\plugins\org.eclipse.birt.report.viewer_2.1.0.N20060628-1351\birt\scriptlib\目录下。
下面代码清单(ServiceReportExample.java)显示了负责解析EMF model的程序片断:
清单1
其中,该程序把从EMF model实例中解析出来的数据对象,保存在一个 Vector 对象中。BIRT 通过解析Script
可以调用该类,从 Vector 对象中获取数据信息。
生成报表的程序逻辑比较复杂。作者创建了一个名为"DesignReport.java",实现了生成报表设计文档(*.rptdesign)的过程,即利用
BIRT Report Design API 创建设计文档中的数据源、数据集、参数和视图中每一个元素。下面代码显示了怎样应用 BIRT
Report Design API 去创建一个简单的表格。
1. 成员函数"design()"包含了创建一个报表的程序逻辑
清单2.
2. 创建数据源
清单3.
3. 创建数据集
创建数据集可以包含两部分操作:
① 创建数据集中的数据列,以及要显示的名字。
清单4
② 创建 Script:BIRT 通过解析 Script,从 ServiceReportExample.class 中获取数据。
a. 创建"open"语句:把数据源指向获取数据信息的 class。在"ServiceReportExample.class"中负责解析EMF
model 的一些包,需要被显示声明导入。BIRT Report Engine 通过解析 Script,调用该类中的"getData()"方法,获取数据信息。
清单5.
b. 创建"fetch"语句:通过解析该语句,将数据从 Vector 对象循序读出,并关联到表格的对应列中。
清单6.
c. 创建"close"语句,并添加到Script对象中
清单7
4. 创建风格和标题
在程序中,作者创建了表格的应用风格和标题:
清单8.
5. 创建表格
在BIRT report中,表格分为三个部分:表头、主体和表尾。下图显示了使用BIRT Report Design工具设计的表格例子,作者用程序实现了创建这个表格的过程,并将表格中每列显示的数据与定义的数据集中的数据列进行绑定。
图7. 使用 Design Report 创建的表格
① 创建绑定信息
注意:在设置表格与数据集的绑定信息时,需要将表格中每一列与数据集中数据列进行关联。
清单9.
② 创建表头
清单10.
③ 创建主体
清单11.
新建一个"Plugin project",把"DesignReport.java"放到这个工程中,运行该插件,调用该类生成一个报表文件:serviceReport.rptdesign。使用
BIRT Design Report 打开该文件,可以发现,用程序生成的文件和用 Design Report 工具设计的文件是完全一样的,预览该文件,可以得到我们想要的结果:
图8. 预览报表
由于 BIRT 项目缺乏相关 API 的描述,给开发者集成 EMF 和 BIRT,使用程序实现 BIRT Report 的创建过程带来了很多问题和挑战。所以,作者给出了一个比较好的提示:使用报表设计工具(Report
Design)创建一个例子,然后根据该例子的 XML Source 视图中元素自身的属性和结构,指导开发者使用 BIRT API
开发报表。
|