ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 扩展 UML 到 C# 转换

扩展 UML 到 C# 转换

原创 Linux操作系统 作者:habug 时间:2009-04-08 15:54:24 0 删除 编辑

简介

IBM® Rational® Software Architect 包含了一系列的预定义转换。其中的一些用于将一个 UML 模型转化为源代码。UML 到 C# 转换,如同其他一些模型到代码转换一样,可以被扩展。本篇文章列出了创建一个简单的扩展示例所需的步骤,该扩展示例演示了此功能的核心能力。

对于 Rational Software Architect 的大多数特性,您要使用标准 Eclipse 扩展机理,创建一个插件和执行特定扩展点来扩展它。本篇文章并没涉及到一般的插件开发,如果您需要这方面的更多信息,您可以查看本文的 参考资源 部分。但是,本文包括了创建以及测试一个转换扩展,所需要的一些插件开发技巧,并将重点放在自定义 C# 转换上 。

您需要扩展转换的原因

下面列出的,是您想要扩展转换可能的几个原因,您可能想要:

  • 向您的方法添加自动记录,记录什么列出参数以及返回类型。
  • 向每一个产生的类型添加作者信息。
  • 更改转换产生的默认方法主体。

在每一种情况下,扩展转换都能帮助您,生成您自定义的资源。

开始

如图 1 所示,当一次 UML 到 C# 转换启动时,它从配置作为转换资源的 UML 模型开始。



UML 到 C# 转换元素

该转换处理整个模型,如图 2 所示。转换浏览了资源,并组成了一个 C# Abstract Syntax Tree(AST),而这又是另外一个 Eclipse 建模框架(EMF)模型。然后转换使用 Java Emitter Template 2 (JET2),来将 AST 转换成 C# 资源 。在本文的结尾,您可以找到目标的一个完整列表。



UML 模型

对于这个简单的示例,您将定义一个简单的,类层次的扩展,每当一次转换转换将一个 UML Class 元素转化成 C# 源文件时,都会激活该扩展。本扩展仅仅搜寻为该类定义的关键字,然后使用它们,来添加与源代码中的类相关的新记录标签。

您需要执行的总体步骤包括:

  1. 为您的转换扩展创建一个新的插件项目。该项目可以与其他的扩展联合起来。但是,为了让这个例子变得简单,您需要从头开始创建一个新的项目。
  2. 添加一系列需要的插件附件。这些插件定义了您正在运行的扩展点,并提供了激活扩展您将需要的 APIs。
  3. 在插件描述器中,定义能识别您将要扩展的转换的扩展点,以及您想要做出更改的其中的点。如果您想要得到关于一个扩展点定义(以及怎样去构建它)的更多具体信息,参见 参考资源 部分中的 有关 Eclipse Plug-in Architecture 的说明(Notes on the Eclipse Plug-in Architecture)部分。
  4. 提供一个 Keyword Documentation Rule 的 Java 工具,每当转换遇到您注册的元素类型时,都会使用到该工具。
  5. 通过启动一个运行时工作台,并执行一次 UML 到 C# 转换,来测试转换。

    创建并配置一个新的插件项目

    您的转换扩展从一个新的插件项目开始。

    1. 选择 File > New > Project。
    2. 从项目类型列表中选择 Plug-in Project,然后点击 Next。
    3. 在 New Plug-in Project 向导的第一个页面中,输入一个有效的项目名。插件的 Eclipse 惯例,是使用一个如图 3 所示的 URI 域。

    图 3. New Plug-in Project 向导
    属性设置以及目标平台
    1. 在第二个界面中(图 4),您应该更改默认的 Plug-in Name 区域。输入 Sample UML to CS Extension.。其他默认的设置可以接受。

    图 4. New Plug-in Project 向导属性页面
    插件属性以及选项

    在最后的页面中,不需要选择一个插件模板,因为那里没有为转换扩展准备的模板,只有新完成的转换。

    1. 清除模板选项并点击 Finish,如图 5 所示。

    图 5. New Plug-in Project 向导最后的页面
    可用模板的列表

    当向导设置完成后,一个新创建的插件项目会生成,并且项目描述器的 Overview 页面会打开,如图 6 所示。



    左边的 Package Explorer, 右边的概述

    接下来的一步,是添加作为附件的一些插件(在切换至 Plug-in Development 视角以后)。这些插件包含了扩展点定义,您将为该点定义提供一个工具,以及在扩展工具中将会用到的 APIs。

    1. 切换至附件标签(在编辑器的底部可以找到它),并添加作为附件的如下插件。
      • com.ibm.xtools.modeler
      • com.ibm.xtools.transform.core
      • com.ibm.xtools.transform.uml2.cs
      • com.ibm.xtools.cli.model

    结果得到的列表应该与图 7 相似。



    窗口底部的标签 

    定义并运行扩展

    接下来要讲的一步,是您将要向一个或多个扩展点提供的工具。

    1. 切换至 Extensions 标签。
    2. 点击 Add 按钮以添加一个新扩展。对话框如图 8 所示。
    3. 输入扩展点 com.ibm.xtools.transform.core.transformationExtensions。
    4. 当找到它时,选中它并点击 Finish 按钮。


    扩展点,向导以及模板

    您需要在扩展点定义中提供更多的信息。您可以在 Extension 标签页面的用户界面中,输入这些值。但是大多数人发现,只编辑 plugin.xml 文件的纯 XML 会更加容易

    当首次定义一个扩展时,会创建该文件(在那之前,并不需要创建文件,所以 New Project 向导并没有创建它)。切换至 plugin.xml 标签,您将会看到 XML 资源,您可以编辑它。

    对于本例,向扩展点添加如列表 1 所示的具体内容。


    列表 1. 扩展申明
    				
       
          
    
             
             
    
             
                
                
             
          
       
    

    扩展元素的主体,在 Rational Software Architect Core Transformation 组件这种情况下(com.ibm.xtools.transform.core.transform),是由扩展点提供者定义的。该扩展预计了 TransformationExtension 子元素(为每一个扩展转换的类型)。这些元素中的每一个,都定义了扩展哪一个转换。

    1. 对于这个简单的例子,用 IDcom.ibm.xtools.transform.uml2.cs.internal.UML2CSTransform. 来指定 targetTransformation。
    2. 您应该为 ID,版本号,名字,以及可用 Boolean 值应用合适的值。

    每一个转换扩展,将子元素定义为一个规则定义,它指定了执行规则界面的类。该类完成了构建转换的大多数工作,提供了放置您自定义的过程逻辑的地方。它作为一个单独的元素定义,因为对于一个单独的类来说,构建转换的大多数部分(也就是类,属性,以及操作)是可能的。

    一旦定义了所有的规则,它们将与 ExtendTransform. 元素一起构建的转换的一部分协调起来。该元素定义了规则要构建转换的一部分。换句话来说,一旦规则被创建,我们需要指定什么时候去使用它们 。

    对于这个简单的例子,每当一个新类被转换时,您都要构建转换 。targetTransform. 的值应该是 com.ibm.xtools.transform.uml2.cs.internal.ClassTransform。目标转换 ID 的完整列表,可以在本文结尾的 附录 段落中找到。

    因为不止一个规则可以构建转换的任意一个特殊部分,所以把它们集中到这里,作为 ExtendTransform. 元素的子元素。可能您在您的项目中只有一个定义的规则,所以这里有一个清晰而简单的映射 。在各种插件的条件下(或者 transformationExtensions,TransformExtension,RuleDefinition,ExtendTransform,或者 AddRule 元素的多种实例), 制作一个与图 2相似的图表,将是有帮助的。元素 RuleDefinition 的 id 必须与元素 AddRule 的 id 相匹配。

    当您完成您的编辑之后,保存文件。您应该注意到,在文件 plugin.xml 靠近线的左部边缘区域,有一个很小的错误图标,该文件指定了执行类。这意味着在项目中不能找到该类。您可以启动 New Class 向导,并使用它来创建类文件。您也可以使用 File > New 菜单手动创建该类。

    1. 不管您以何种方式在 Eclipse 中创建 Java 类,在预定的包裹中创建一个,并给它起一个合适的名字。

    您将要扩展 Rational Software Architect 转换框架类com.ibm.xtools.transform.core.AbstractRule。因为该类是一个超类,所以只有三个应该被忽略的方法。

    • canAccept:其作用像一个过滤器,决定该规则是否可以接受资源元素
    • createTarget:用于从资源元素中创建目标元素
    • isSourceConsumed:允许或阻止在该资源元素上的进一步规则执行

    其中每一个方法接受一个 transformation context object,您可以对它进行查询,以获取对资源以及目标对象的访问权。一个转换内容对象,是与转换相关的各种属性的集合体,该集合体包括了总体转换配置属性(从 Preferences 中),以及当前执行转换的属性 。

    利用这些信息,您可以决定是否处理特定的类(canAccept),或者对于该类的进一步处理是否终止 (isSourceConsumed)。如果该扩展接受了内容,那么方法createTarget()用于对转换做出实际构建。换句话讲,您使用 canAccept() 方法,来进一步决定什么时候执行您的规则。您的扩展的逻辑,将出现在 createTargetMethod() 中。您也可以决定,是否继续处理与规则相关的元素。

    对于这个简单的转换扩展,在 isSourceConsumed 方法中返回 false,以指示进一步的处理应该继续(如列表 2 所示)。这同时还可以看出,扩展并不意味着,这些特殊元素的所有转换工作都已完成 。

    继续处理本例,在 canAccept() 方法中指示,当资源元素是 UML Class 类型,并且那里至少有一个定义的关键字时,您可以接受一个特殊类,如果那里没有任何关键字,那么您就不需要再做什么,这样表示您并不感兴趣。通过作为一个论题传递的转换内容,访问资源 UML 类。

    内容中的 getSource() 方法向一个 UML 类返回一个引用,因为您在扩展点中指定,您只对 Class 转换感兴趣。向一个 UML 类输入资源对象,然后从该对象中获得关键字列表。如果列表为空,则返回 false。如果列表中含有关键字,那么您就可以访问 createTarget() 方法。这就是您想要构建转换的地方 。


    列表 2. Java 规则类工具
    				
    				package com.ibm.rsa.cs.extension.sample;
    
    import java.util.Iterator;
    
    import com.ibm.xtools.cli.model.CompositeTypeDeclaration;
    import com.ibm.xtools.transform.core.AbstractRule;
    import com.ibm.xtools.transform.core.ITransformContext;
    import org.eclipse.uml2.uml.Class;
    
    public
    				class ClassKeywordDocRule extends AbstractRule {
    
    	private
    				static
    				final String NEW_LINE = System.getProperty("line.separator");
    |-------10--------20--------30--------40--------50--------60--------70--------80--------9|
    |-------- XML error:  The previous line is longer than the max of 90 characters ---------|
    	
    	public
    				boolean canAccept(ITransformContext context) {
    		Object source = context.getSource();
    		if (!(source instanceof Class))
    			return
    				false;
    		
    		Class umlClass = (Class)source;
    		return (umlClass.getKeywords().size() > 0);
    	}
    	
    	public
    				boolean isSourceConsumed(ITransformContext context) {
    		return
    				false;
    	}
    
    	protected Object createTarget(ITransformContext context) throws Exception {
    		CompositeTypeDeclaration target = 
                                (CompositeTypeDeclaration)context.getTarget();
    
    		if (target == null)
    			return
    				null;
    		
    		String documentation = target.getDocumentation();
    		
    		Class sourceClass = (Class)context.getSource();
    		Iterator keywords = sourceClass.getKeywords().iterator();
    		while (keywords.hasNext()) {
    			String keyword = (String)keywords.next();
    			documentation = " _cnnew1@" + keyword + NEW_LINE + documentation;
    		}
    		target.setDocumentation(documentation);
    		return target;
    	}
    }
    

    执行 createTarget() 方法的第一步,是访问转换此部分的资源以及目标对象。因为在转换处理一个 UML 类时,您已经定义了激活的扩展,所以您可以安全的向一个 Abstract Syntax Tree (AST)访问的 CompositeTypeDeclaration 对象,输入目标对象。

    AST 是 C# 元素的模型。所以,一个 C# 程序可以由一个 AST 的实例来代表。例如,一个类可以由一个 CompositeTypeDeclaration 的实例来代表,用 kind 当作 com.ibm.xtools.cli.model.TypeConstants.CLASS。插件 com.ibm.xtools.cli.model 为管理 C# 源代码,提供了所有的 APIs。

    如果您打算添加关键字,以作为记录中的一部分,那么,您就必须从获得已处理的记录开始。首先,从已存在的目标中提取已处理过的记录。注意如果没有任何已存在的 C# 源代码,那么在目标对象中就得不到任何记录。在所有的模型元素都被转换完之后,那么新生成的和已存在的代码将会同时出现 。

    本文在这里并不讨论关于 AST 的任何细节,除非当扩展需要向生成的代码添加新元素时,才会涉及到一些。通过访问 AST 的方法来做到这一点。对于本例,您想要向类的记录文件添加一个新的标签。对象 CompositeTypeDeclaration 使用一个 String 来储存记录。只要您愿意,您可以编辑该记录文件,并将其设置好 。

    为了决定添加什么关键字,从转换内容中访问资源对象,并将其传递给一个 UML 类。从这个对象中,获取关键字的列表(与在执行 canAccept() 方法时您的操作相似)。对于该列表,对关键字进行重复操作,创建一个新的 @keyword 线,以作为记录的前缀 。

    方法必须返回一个目标对象,默认条件下,添加规则 thisextension 以作为 targetTransformation 的最终规则(再次参考图 2中的图表)。因此,它处理该转换的“so far”目标。除非扩展规则从目标转换(一个不同 AST 类的转换,或者同一 AST 类的不同对象)中更改了返回元,否则扩展规则不会返回作为目标的同一对象。

    这就已经完成了转换扩展的创建以及执行 。

    测试扩展

    既然已经定义并执行了扩展,那么您就需要测试它。通过创建一次调试配置来进行测试,该调试配置将会在一个新的运行时平台中打开 。

    1. 为了创建该配置,从主菜单中选择 Run > Debug。
    2. 在对话框中,创建一个新的 Eclipse Application 配置,并给它起一个合适的名字。
    3. 您可以改变工作区的位置:选择一个新位置,以避免无意识中影响到一个已存在的工作区,这是一个明智的做法。
    4. 其余的默认设置是可以接受的(图 9)。



    左边的树状图,右边的标签

    1. 当您完成编辑配置以后,按下 Debug 按钮以启动一个 Eclipse 的新实例。

    该新实例,将会把转换扩展(您刚刚创建的)当做一个插件安装。

    为了测试扩展,您将需要创建一个新的 UML 项目,并向新的 Eclipse 内核的实例,引入一个 Visual Studio C# 项目。您也可以在创建一个新转换配置时,通过点击 Create New Target Container按钮来引入 Visual Studio C# 项目。

    1. 在 UML 模型中,创建一个测试包和类。结果得到的工作区应该和图 10 所示的相似。



    右边的配置板,左边的视图

    接下来,您需要向类添加一个关键字,因为您的扩展,只会处理那些有一个已定义关键字的类。

    1. 选择类(要么在图表中要么在 Project Explorer 项目中),然后在 Properties 试图中选择 Stereotypes 子标签。
    2. 在 Keywords 区域输入一些文本,如图 11 所示。



    顶部的图表, 底部的标签以及数据

    要设置文本项目以及模型,您需要创建一个新转换配置,该配置定义了 UML 到 C# 转换的主要参数。

    1. 从主菜单中选择 File > New。
    2. 然后,在 Transformations 目录下,选择一个新的 Transformation Configuration 并点击 Next,如图 12 所示。



    从列表中选择一个向导

    这里有许多 Rational Software Architect 中包含的转换类型。

    1. 选择 UML to C# 转换,因为这是您需要为之而创建的扩展。
    2. 给它起一个合适的名字,如图 13 所示(该名字将在 UML 项目中用做配置文件的文件名)。



    树状图中的前置转换列表

    1. 在一个转换配置中,您需要指定的第一件事,是资源模型以及目标项目。确保选择了 Models 文件夹下的 UML 模型,而不是实际的 .emx文件。
    2. 通过点击 Create New Target Container 按钮来创建目标,如图 14 所示。



    左边的资源, 右边的目标

    这将启动如图 15 所示的 Net Solution Import 向导。

    1. 确保在 VS 2005 中打开了 .NET Solution,并使用引入向导,来向 Rational Software Architect 工作区引入 .NET Solution 。


    图 15. 引入 .NET solution
    输入方案文件路径

    1. 使用 Browse 按钮,来选择合适的要被引入的 Visual Studio C# 项目。一旦引入 Visual Studio C# 项目,那么它将会在目标列表中显示出来。
    2. 为转换选择引入的 C# 项目作为 Selected target(图 16),并点击 Next。



    左边的资源以及右边的目标

    在这里您并不会深入到其他转换配置选项的具体细节中。

    1. 点击 Finish 按钮以创建转换。

    既然配置已经被创建起来,那么现在就可以激活它。从该项目的生命考虑,它并不需要被重新创建。

    1. 为了激活转换以及您对它所做的扩展,在 Project Explorer 视图中右击转换配置,并选择 Transform. > UML to C#(图 17)。



    菜单命令

    1. 为了检查转换的结果,切换至 Visual Studio IDE(图 18)。您可以看到,在类的记录文件中,怎样添加一个关键字。



    左边的代码,右边的树状图

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/14780873/viewspace-586740/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-07-07

  • 博文量
    211
  • 访问量
    362647