基于RSA模型转换框架的开发

日期: 2008-06-04 作者:毛新生孙瑛霖 来源:TechTarget中国

  本文首先介绍模型转换的基本概念,然后介绍RSA模型转换框架,之后本文以两个具体的例子介绍如何在RSA开发平台中以模型转换框架为基础创建和扩展模型转换。


  1 内容简介


  模型转换框架(Model Transformation Framework)是IBM最新开发平台RSA(Rational Software Architect)中的重要组成部分,其主要功能是在模型驱动的开发过程中,为实现各种模型之间的转换提供基础平台的支持。基于这个框架,能够很容易地实现模型之间的转换程序,以及扩展已有的转换。


  本文首先介绍模型转换的基本概念,然后介绍RSA模型转换框架,之后本文以两个具体的例子介绍如何在RSA开发平台中以模型转换框架为基础创建和扩展模型转换。


  2 模型转换


  MDA(Model Driven Architecture,模型驱动的体系结构)和MDD(Model Driven Development,模型驱动的开发)是当今软件领域最热门的话题。相比于传统的以代码为中心的开发模式,MDA和MDD则是以模型为中心,在开发的各个阶段,都使用模型来描述系统特征。


  模型转换贯穿于MDD的全过程。系统开发初期,为了刻画系统特征,一般会创建系统的分析模型。分析模型是一个比较粗糙的模型,相当于草图的作用,只用于辅助分析。随着系统的特征越来越清晰,系统的设计模型会慢慢形成。设计模型能够比较精确地描述系统,是系统实现的基础。从设计模型可以很容易地导出系统的实现模型。实现模型包括具体的代码、脚本、配置文件等等。这是一个自顶向下、逐层细化的过程,从高层的抽象模型开始,经过一系列的模型转换,最终生成底层的系统实现。



  图1 模型转换
 
  由此可见,模型转换在模型驱动的开发和设计中起着非常重要的作用。


  3 RSA模型转换框架


  RSA(Rational Software Architect)是IBM的新一代软件开发平台,代号为Atlantic。RSA基于开放/可扩展的Eclipse 3.0构建,全面支持UML 2.0标准和模型驱动的开发方法。RSA为开发当今日益复杂的应用系统提供了一个强大的的开发环境,整合了UML建模、J2EE、XML、web services、C++开发工具以及RUP过程指南等诸多功能,是软件架构师/开发人员的首选工具。


  为了支持模型驱动开发过程中各种模型之间的转换,RSA提供了一个功能强大、易于扩展的模型转换框架(Model Transformation Framework),该框架是一个基于规则的执行引擎,基于该框架,可以很方便地定义模型转换规则,实现各种模型之间的转换。RSA模型转换框架实现了模型转换的注册和配置管理,提供了统一的运行界面,以及各种开发向导。


  RSA预装有一些常用的模型转换,包括UML2JAVA、UML2CPP、UML2EJB,这三个转换分别以UML模型为输入,生成对应的Java程序、CPP程序和EJB。关于如何使用RSA预装的模型转换,请读者参阅RSA的相关文档。


  下面简单介绍RSA模型转换相关的一些概念:


  Transformation(转换):以源模型对象为输入,目标模型对象为输出,实现模型之间的转换。每个转换由若干条转换规则组成。
  Rule(转换规则):以源模型对象中某部分为输入,目标模型对象的对应部分为输出,实现了功能逻辑上相对独立的一部分转换任务。
  Transformation Context(转换上下文):转换上下文是转换过程中转换规则之间共享数据的容器。在转换的执行过程中,转换上下文会在规则的实现之间传递,每一个规则可以向上下文中存放需要共享的数据,也可以从中获取所需的数据。
  Transformation UI:模型转换框架会为每个转换提供一个默认的配置管理界面,让用户指定源模型,目标模型,以及所需的一些转换属性。如果需要定制更加复杂的界面元素,则需要模型转换的开发人员对默认的界面加以扩展。


  至此,读者应该已经对RSA模型转换框架有了总体的了解,本文余下部分将结合具体的例子,介绍如何在RSA中基于模型转换框架开发新的模型转换和扩展已有的模型转换。


  4 基于RSA模型转换框架的开发


  本节以一个具体的模型转换为例,介绍如何在RSA中基于模型转换框架开发新的模型转换。这个转换名为Model2Text,接受的输入为UML模型中的Class、Package,或者Model,如果输入为Class,则遍历类的属性、方法、参数,将这些信息输出到控制台,如果输入为package或者model,则遍历package和model下面的每一个类,将类的信息打印到控制台。


  4.1 创建新的插件工程


  通过新建工程向导创建一个插件工程。由于模型转换框架是作为eclipse插件集成在RSA中,因此模型转换工程也必须是一个eclipse插件工程,这样才能够使用转换框架提供的组件。


  4.2 添加TransformationProviders扩展点


  为了创建一个新的模型转换,需要从TransformationProvider扩展点进行扩展。首先添加所需的插件:



  图2 开发模型转换所需的插件
 
  然后添加TransformationProviders扩展点,该扩展点的ID为com.ibm.xtools.transform.core.transformationProviders。


  4.3 创建模型转换的入口:TransformationProvider


  从TransformationProviders扩展点扩展,添加TransformationProvider:



  图3 创建TransformationProvider
 
  添加TransformationProvider之后需要创建对应的实现类,这个类需要继承自模型转换框架提供的接口com.ibm.xtools.transform.core.AbstractTransformationProvider,是模型转换框架执行引擎调用模型转换的入口点,主要提供两个方法:


  createTransformation 创建模型转换的实例,返回给调用引擎
  validateContext 验证模型转换的执行上下文,从上下文中可以获取源模型和目标容器,进行验证。验证的结果会反映在模型转换的配置管理界面上。本例验证源模型是否Class、Package或者Model。


  4.4 创建Transformation


  本例的Model-to-Text转换在plug-in.xml中定义如下:


  <Transformation
   version=”1.0″
   name=”%Transformation.name.classtotext.console”
  transformGUI=”com.ibm.xtools.transform.samples.modeltotext.TransformGUI”
   keywords=”%Transformation.keywords.classtotext.console”
   author=”%Transformation.author”
   groupPath=”%Transformation.groupPath”
   sourceModelType=”UML2″
  description=”%Transformation.description.classtotext.console”
   document=”doc/classToTextToConsole.html”
   targetModelType=”None”
  id=”com.ibm.xtools.transform.samples.classtotext.console.root”>
  </Transformation>
 
  Transformation的主要属性:


  Id 注册在模型转换框架中唯一的id。可以通过这个id引用这个模型转换
name 模型转换的名字,也即最终显示在Transformation弹出菜单中菜单项的内容
sourceModelType 源模型的类型,如UML2、Resource等等。本例选择UML2。
  targetModelType 目标模型的类型,由于本例是将源模型中类的信息输出到控制台,所以选择None
  transformGUI 自行定制的配置界面的实现类名。如果不指定,则转换框架会提供一个缺省的界面
  document 该模型转换相关文档存放的位置


  4.5 为transformation定义规则


  每个模型转换都由若干转换规则组成,每条规则实现了逻辑上相对独立的一部分转换功能,若干条规则组合在一起实现整个转换功能。转换规则的实现类应该实现模型转换框架中提供的com.ibm.xtools.transform.core.AbstractRule接口,一般需要实现如下两个方法:


  createTarget 从转换上下文对象中获取源模型对象,生成目标模型中相应的对象canAccept 该方法会在执行转换规则之前调用,验证源模型,通过验证则调用规则,否则执行引擎会忽略该规则。


  本例定义了4条转换规则:ClassRule、OperationRule、ParameterRule、PropertyRule,分别操作源模型中的类、操作、参数和属性对象,并输出信息到控制台。


  转换规则需要在模型转换实例初始化的时候添加:


  UML2Package uml2 = UML2Package.eINSTANCE;
  addByKind(uml2.getClass_(), new ClassRule());
  addByKind(uml2.getProperty(), new PropertyRule());
  addByKind(uml2.getOperation(), new OperationRule());
  addByKind(uml2.getParameter(), new ParameterRule());
 
  这段代码将4条规则添加到模型转换中,并指定每条规则所能够接收的源模型对象的类型。


  4.6 运行测试


  至此,Model-to-Text转换已经编写完成,下面开始运行测试。由于模型转换本身是一个Eclipse插件工程,所以必须从RSA中再启动一个RSA Workbench实例,将Model-to-Text插件加载运行。


  workbench启动之后,切换到modeling视图,选择Modeling菜单->Transform->Configure Transformations,打开模型转换配置界面,可以看到,Model-to-Text转换已经注册到模型转换框架中:



  图4 Model-to-Text转换已经注册到模型转换框架中
 
  创建一个UML模型,新建一个类Account,并添加一些属性和操作:



  图5 Account类
 
  然后在Account类上右击,从弹出菜单中选择Transformations -> Class to Text -> console,开始执行转换。该转换接收Account类作为源模型对象,将Account类的信息输出到控制台:


  Class: Account
 Attribute: id
 Attribute: balance
 Operation: setID
  Parameter: id
 Operation: getID
  Parameter: ReturnResult
 Operation: setBalance
  Parameter: balance
 Operation: getBalance
  Parameter: ReturnResult
 
  在模型编辑器中创建一个Component,作为输入再次执行Model-to-Text转换,由于Component不能通过源模型认证,因此模型转换框架在配置界面上报告错误:



  图6 源模型对象验证错误
 
  如果需要对模型转换进行调试,则需要以Debug模式启动RSA Workbench,之后便可以在源代码中设置断点,进行调试。


  5 扩展模型转换


  RSA模型转换框架提供了良好的可扩展性,用户可以根据具体的应用需求,在已有模型转换的基础上增加一些转换规则进行扩展。例如,RSA预装的UML2Java转换是一种基础性的转换,在实际应用中,可以对其进行扩展,在生成的Java代码中增加一些版权声明。


  一般来说,一个模型转换通常会根据功能划分成若干个转换,每个转换由若干规则组成,实现一部分独立的功能,例如,UML2JAVA总的转换程序为UML2JavaTransform,按照转换的不同阶段,划分为PropertyTransform,OperationTransform等等,在这些转换之间,通过转换上下文共享数据。这样,在对其进行扩展的时候,需要根据具体的需要,在某些阶段的模型转换中增加转换规则,并通过转换上下文共享数据。


  对于一个已有的模型转换,可能存在很多扩展,在转换执行的时候,所有的这些扩展转换规则都会被加载执行,那么用户如何只选择执行他们需要的扩展规则,而忽略掉其他扩展规则呢?在模型转换的开发过程中,一般使用UML Profile来解决这个问题。在扩展模型转换的时候,开发者往往会提供一个UML Profile,用户使用这个profile中定义的stereotype对需要执行扩展转换规则的源模型对象作标记,扩展转换规则会根据特定的stereotype来过滤源模型对象,选择执行还是不执行。


  本节以一个具体的例子来介绍如何基于RSA模型转换框架扩展系统已有的模型转换。本例将扩展UML2JAVA转换,扩展之后,用户对UML模型执行UML2JAVA的时候,扩展规则会为Class中的属性添加Get和Set方法,对于只读属性,只添加Get方法。这个扩展的实现包括两条扩展规则和一个UML profile,profile提供了一个stereotype,用户在源模型中对需要生成get和set方法的属性上应用这个stereotype。DefineGetterSetterRule添加到UML2JAVA转换中的PropertyTransform,用于收集源模型中需要生成get和set方法的属性,并存放到转换上下文中,createGetterSetterRule添加到ClassTransform中,该规则从转换上下文中获取DefineGetterSetterRule之前设置的属性信息,创建对应的get和set方法,如果属性只读,则只创建get方法。


  下面介绍主要的开发步骤:


  5.1 新建插件工程


  模型转换的扩展也必须实现为Eclipse的插件。


  5.2 创建UML Profile


  关于如何创建UML Profile,请读者参阅RSA相关的帮助文档。本例所用profile的id为GetSetProfile,包含一个名为GetterAndSetter的stereotype,扩展自Property:



  图7 GetSetProfile
 
  5.3 实现扩展规则


  DefineGetterSetterRule的实现:


  public boolean canAccept(ITransformContext context) {
  // 本规则接受的源模型对象为应用了GetterAndSetter Stereotype的Property
  if (context.getSource() instanceof Property){
   Property attribute = (Property)context.getSource();
   if(attribute.getAppliedStereotype(GETTER_SETTER_STEREOTYPE) !=   null){
     return true;
   }
  }
  return false;
  }
  protected Object createTarget(ITransformContext context) {
    /**
     * 记录需要处理的property的信息,并存放在转换上下文中,供  createGetterSetterRule 使用
   */
  Object[] propertyInfo = new Object[2];
  propertyInfo[0] = context.getSource();
  propertyInfo[1] = context.getTarget();
  List properties = (List)context.getPropertyValue(“createGetAndSet”);
  if (properties == null){
  ITransformContext classContext = context.getParentContext();
  List list = new ArrayList();
 list.add(propertyInfo);
 classContext.setPropertyValue(“createGetAndSet”,list);
  }else{
  properties.add(propertyInfo);
  }
  return propertyInfo[1];
  }
 
  createGetterSetterRule的实现请参考本文附带的代码。


  5.4 扩展UML2JAVA转换


  为了扩展模型转换,需要从com.ibm.xtools.transform.core.transformationExtensions扩展点进行扩展,将之前实现的转换规则添加到需要被扩展的模型转换中。本文以DefineGetterSetterRule为例,介绍如何添加扩展规则:


  <TransformationExtension
  version=”1.0.0″
    name=”DefineGetterAndSetter”
    enabled=”true”
  targetTransformation=”com.ibm.xtools.transform.uml2.java.internal.UML2JavaTransform”
  id=”com.ibm.xtools.transform.samples.uml2java.getterSetter.extension.defineOperation”>
<RuleDefinition
  name=”DefineGetterAndSetterOperation”
  class=”com.ibm.xtools.transform.samples.uml2java.getterSetter.DefineGetterSetterRule”
  id=”com.ibm.xtools.transform.samples.uml2java.getterSetter.DefineGetterSetterRule”>
</RuleDefinition>
<ExtendTransform
    targetTransform=”com.ibm.xtools.transform.uml2.java.internal.PropertyTransform”>
   <AddRule
id=”com.ibm.xtools.transform.samples.uml2java.getterSetter.DefineGetterSetterRule”>
   </AddRule>
</ExtendTransform>
</TransformationExtension>
 
  targetTransformation属性指定了被扩展的模型转换,RuleDefinition定义了扩展规则,ExtendTransform则将扩展规则添加到具体的转换中。


  5.5 运行测试


  至此,对UML2JAVA转换的扩展实现已经完成,从RSA再启动一个RSA Workbench实例,加载扩展转换插件。创建一个UML模型,在模型中创建Account类:



  图8 Account类
 
  Account类包含四个属性,其中password和balance属性应用了GetterAndSetter Stereotype,在转换之后会生成对应的Get和Set方法,id属性也应用了GetterAndSetter Stereotype,但id为只读属性,因此在转换之后只会生成对应的Get方法。userName没有应用这个Stereotype,则不会生成Get和Set方法。以Account类为源模型,执行UML2JAVA转换,生成Java程序:



  由生成的代码可以看出,在转换框架执行UML2JAVA转换的时候,会将两条扩展规则加载执行。


  6 总结


  模型转换在模型驱动的开发过程中起着重要的作用。RSA提供了一个功能强大、易于扩展的模型转换框架。该框架是一个基于规则的执行引擎,模型转换的开发者只需将转换定义为一系列转换规则即可,模型转换框架会负责加载执行规则,并提供统一的模型转换配置管理,在很大程度上简化模型转换的开发过程。


  关于作者


  IBM中国软件开发实验室SOA设计中心 是IBM全球四个SOA设计中心中最大的一个,成立一年多来,已经取得了可喜的成果。我们在全球范围内实施了多个 SOA 应用项目,为多个行业的客户提供了 SOA 解决方案。我们正在实施的 SOA 项目涵盖了很多的重要行业,包括零售业、航运业、电力、银行、保险等等。通过这些不断增长的成功案例,我们不仅深入地推广了 SOA 的理念,树立了 SOA 成功实施的范例,也为我们的队伍积累了经验,培养了人才。与此同时,我们还是 IBM 开发 SOA 的软件平台 — SOA Integration Framework — 的主力军。该产品基于模型驱动的思想,旨在最大化地重用软件资产,它为 SOA 项目的实施提供了一整套源自成功实践的方法论,设计范式和工具集。它的出现将极大地方便 SOA 系统架构师、设计人员、开发人员快速地开发 SOA 应用项目。


  参与本系列撰写的主要技术人员包括:


  毛新生 IBM 中国软件开发实验室 资深经理, SOA计中心中国区 首席架构师
  何蕾 IBM 中国软件开发实验室 SOA设计中心 高级软件工程师
  孙瑛霖 IBM 中国软件开发实验室 SOA设计中心 软件工程师
  田晨 IBM 中国软件开发实验室 SOA设计中心 软件工程师
  王强 IBM 中国软件开发实验室 SOA设计中心 软件工程师

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐