内容


使用 Rational Software Architect V7 扩展 UML 到 Java 5 的转换

Comments

关于 Rational Software Architect 中的 Java 5 转换特性

IBM Rational Software Architect 包括许多预定义的转换,一些将 UML 模型转换为源代码。V7 引入了包括 Java 5 特性的转换。像其前辈一样,该转换可以扩展。本文带您经历了创建示范该功能的核心能力的简单实例的必要步骤。

如同 Rational Software Architect 中的大部分特性一样,要进行扩展,您要使用标准的 Eclipse 扩展机制,创建插件并实现具体的扩展点。本文不介绍一般的插件开发(参见参考资料部分的推荐文章和实例)。取而代之,本文着重于创建和测试转换扩展所足够的插件开发技能。

图 1. 总的转换结构
总的转换结构图
总的转换结构图

当调用转换时,从 UML 模型、包、类、接口,或枚举元素开始,这依赖于您调用转换时选择的内容。转换将影响所选择的元素(或者如果没有选择元素,将包含整个模型)及该元素所包含的所有元素。在此为转换扩展作者提供很多机会来接近并继续整体的转换。扩展只瞄准整体转换的一个部分。您将在附录中找到目标的完全列表(参见下载)。

对于该简单的实例,您将定义一个每次转换准备将 UML 类元素转换为 Java 源文件时调用的简单的类级扩展。该扩展只不过寻找为该类定义的任意关键字,并使用它们在源代码中添加与类相关的新 Javadoc 标签。

您将依照这些步骤:

  1. 为您的转换扩展创建新的插件工程。该工程可能与其他扩展相结合,然而,为了使该实例简单,您将从零开始创建新的工程。
  2. 添加一组必需的插件依赖性。这些插件定义了您将实现的扩展点,并且提供您调用扩展所需要的 API。
  3. 在插件描述符中定义扩展点,这确定出您将扩展的转换,以及转换中您想要处理的点。
  4. 提供每次当转换遇到您指示的元素类型时要调用的类规则的实现。
  5. 通过调用运行时工作平台并运行 UML-to-Java 5 转换来测试转换。

步骤 1. 创建并配置新的插件工程

转换扩展以新的插件工程开始:

  1. 选择菜单 File > New > Project,并从工程类型的列表中选择 Plug-in Project ,并单击 Next
  2. New Plug-In Project 向导的第一页,输入有效的工程名。插件的 Eclipse 规约是使用像图 2 中显示的 URI 领域。
图 2. New Plug-in Project 向导
New Plug-in Project 向导的截屏
New Plug-in Project 向导的截屏
  1. 在第二页中(图 3),更新默认的 Plug-in Name 字段,保留默认值是可接受的。
图 3. New Plug-in Project 向导 Properties 页
New Plug-in Project 向导 Properties 页的截屏
New Plug-in Project 向导 Properties 页的截屏

在最后一页上,没必要选择插件模板,因为没有针对转换扩展的模板,只有对新的完全的转换的模板。

图 4. New Plug-in Project 向导最后一页
New Plug-in Project 向导最后一页的截屏
New Plug-in Project 向导最后一页的截屏
  1. 取消模板选项,并点击 Finish 按钮(图 4。)

图 4. New Plug-in Project 向导最后一页。当完成向导时,就会创建一个新的插件工程并且打开工程描述符的 Overview 页(图 5)。

图 5. 新工程的结构
新工程的结构的截屏
新工程的结构的截屏

步骤 2. 添加必需的插件依赖性

下一个步骤是作为依赖性添加一些插件。这些插件包含用于实现的扩展点定义,以及将在扩展的实现中使用的 API。

  1. 切换到 Dependencies 选项卡(在该编辑器的底部),并将以下插件作为依赖性添加:
    • com.ibm.xtools.modeler
    • com.ibm.xtools.transform.core
    • com.ibm.xtools.transform.uml2.java5
    • org.eclipse.jdt.core
  2. 验证添加了插件。结果的列表应该看起来类似与图 6。
图 6. 依赖的插件
依赖的插件的截屏
依赖的插件的截屏

步骤 3. 定义并实现扩展

下一个步骤是声明,您将向一个或多个扩展点提供一个实现。

切换到 Extensions 选项卡,并单击 Add 按钮添加新的扩展。您将会看到图 7 中所示的对话框。输入该扩展点:com.ibm.xtools.transform.core.transformationExtensions。当您找到它时,选择并单击 Finish。

图 7. New Extension 对话框
New Extension 对话框的截屏
New Extension 对话框的截屏
  1. 需要向扩展点定义中提供更多的信息。可以通过 Extension 选项卡页上的用户界面来输入这些值。然而,大多数人发现编辑 plugin.xml 文件的原始 XML 更容易。该文件是在首次定义扩展时生成的(在此之前,它不是必要的,因此,New Project 向导没有创建它)
  2. 切换到 plugin.xml 选项卡,您将看到您可以编辑的 XML 源文件。
  3. 对于本实例,向扩展点添加清单 1 中所示的细节。
清单 1. 扩展声明
     <extension point="com.ibm.xtools.transform.core.transformationExtensions" >
   
      <TransformationExtension version="1.0.0"
            name="My UML to Java5 Transformation Extensions"
            enabled="true"
            targetTransformation=
            "com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform"
            id="com.ibm.rsa.java5.extension.sample.transformationExtensions.id">

         <RuleDefinition
         	name="Javadoc Keyword Rule"
         	class="com.ibm.rsa.java5.extension.sample.ClassKeywordJavadocRule"
         	id="com.ibm.rsa.java5.extension.sample.ClassKeywordJavadocRule.id"/>

         <ExtendTransform
			targetTransform=
			"com.ibm.xtools.transform.uml2.java5.internal.ClassTransform">
            <AddRule id="com.ibm.rsa.java5.extension.sample.ClassKeywordJavadocRule.id"/>
         </ExtendTransform>

      </TransformationExtension>
   
   </extension>

扩展元素体是由扩展点提供者定义的。在这种情况下,它是 Rational Software Architect Core Transformation 组件。该扩展要求 TransformationExtension 子元素(每个对应要扩展的一种类型的转换)。每一个元素定义要扩展的是哪个转换。

  1. 对于此简单的实例,为 targetTransformation 指定com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform 的 ID。
  2. 为 ID 提供适当的值:版本号、名称,和 enabled 的 Boolean 值。

每个转换扩展定义,就像子元素一样,指定实现规则接口的类的规则定义。该类执行了关于转换的大部分工作。它被定义为单个的元素,因为单个类对转换的多个部分(举例来说,类、属性,和方法)做出贡献是可能的。

当定义了所有规则之后,它们与转换的一部分相匹配,它们用 ExtendTransform 元素对该转换做出贡献。该元素定义了规则将贡献的转换的一部分。对此,您希望在每次转换新类时,对扩展做出贡献,并且 targetTransform 的值应该是 com.ibm.xtools.transform.uml2.java5.internal.ClassTransform。您可以从本文页面上下载的附录中包含目标转换 ID 的完整列表(参见参考资料)。

假设一个以上的规则可以贡献于转换的任意特殊部分,那么在此将它们作为 ExtendTransform 元素的子元素而收集。您在项目中只定义了一个规则,由于您正在使用它。

注意:
RuleDefinition 元素中的规则的 ID 必须与 AddRule 元素中的匹配。

步骤 4. 提供类规则的 Java 实现

当您完成该文件的编辑时,将其保存。您应该注意 plugin.xml 文件中代码旁边的,左边空白中的,指定实现类的小错误图标。这表明在工程中找不到该类。

  1. 您可以双击图标,然后选择 Create a new class 的提示。这将调用 New Class 向导,您可以使用该向导来创建类文件。您还可以使用 File > New 菜单手动创建类。不论您喜欢使用哪种方式在 Eclipse 中创建 Java 类,都要在指定的包中,用正确的名字创建。
  2. 为了尽可能简单地实现,继承 Rational Software Architect 转换框架类 com.ibm.xtools.transform.uml2.imple.internal.java5.ClassRule。该类作为超类,只有三个方法应该覆盖。
    • canAccept
    • createTarget
    • isSourceConsumed

这三个方法都接受转换环境对象,可以查询它们来访问源和目标对象。有了该转换,您就可以决定您是否想要处理这个特殊的类(canAccept)或者应该停止对该类的进一步处理(isSourceConsumed)。如果该扩展接受了该环境,那么将使用 createTarget() 方法来对转换做出实际的贡献。

  1. 对于此简单的转换扩展,在 isSourceConsumed 方法中返回 False,说明应该继续进一步处理,并且说明该扩展不意味着完成了该特殊元素的转换的所有工作。
  2. 说明当至少定义了一个关键字时,您可以接受特殊的类。如果没有关键字,您没有什么要做的,那么说明您是不感兴趣的。您可以通过作为参数传递的转换环境来访问源 UML 类。环境中的 getSource() 方法应该返回对 UML 类的引用,因为我们在扩展点中指定我们只对 Class transforms 感兴趣。
  3. 向 UML 类输入源对象,然后从中获得关键字列表。如果列表是空的,那么返回 False

如果有关键字,那么您可以期望调用 createTarget() 方法。这是期望您对转换做出贡献的地方。

清单 2. Java 规则类实现
package com.ibm.rsa.java5.extension.sample;

import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.uml2.uml.Class;

import com.ibm.xtools.transform.core.ITransformContext;
import com.ibm.xtools.transform.uml2.impl.internal.java5.ClassRule;

public class ClassKeywordJavadocRule extends ClassRule  {

	protected Object createTarget(ITransformContext context) {
		TypeDeclaration target = (TypeDeclaration) context.getTarget();
		Javadoc javadoc = target.getJavadoc();
		List tags = javadoc.tags();

		AST ast = target.getAST();
		
		Class umlCls = (Class) context.getSource();
		EList keywords = umlCls.getKeywords();
		
		for (Iterator iter = keywords.iterator(); iter.hasNext();) {
			String keyword = (String) iter.next();
			TagElement tag = ast.newTagElement();
			tag.setTagName("@" + keyword);
			tags.add(tag);
		}
		return target;
	}

	public boolean isSourceConsumed(ITransformContext context) {
		return false;
	}

	public boolean canAccept(ITransformContext context) {
		Class umlCls = (Class) context.getSource();
		return umlCls.getKeywords().size()>0;
	}
	
}

当实现 createTarget() 方法的时候,开发人员通常做的第一件事是访问转换的这个部分的源和目标对象。因为当转换处理 UML 类时,您已经定义调用该扩展,所以您可以安全地向 Abstract Syntax Tree(AST)TypeDeclaration 对象输入目标对象。Eclipse Java Developer Tools(JDT)工程为处理 Java 源代码提供所有的 API。AST 是为 Eclipse 分析源代码的对象模型。当调用该方法时,转换框架就生成新的 TypeDeclaration 对象。应该注意的是,如果有任何现有的 Java 源代码,那么在目标对象中是不可用的。当转换完所有的模型元素之后,将新生成的代码和现有的代码合并。

除了提到当扩展需要向生成的源代码中添加新元素时,通过对 AST 对象调用方法来完成,对 AST 的详细讨论超出了本文的范围。对于此简单的实例,您仅仅将向类定义的 Javadoc 注释中添加新的 Javadoc 标签。Javadoc 是 AST 的对象类型,并且从 TypeDeclaration 对象中获得。

  1. Javadoc object 中,获得组成 Javadoc 的标签列表。您可以从生成的源代码中添加(或删除)标签。
  2. 要决定添加哪个标签,在转换环境中访问源对象,并将其转换为 UML 类。在该对象中,您获得了关键字列表(类似于您实现 canAccept() 方法时所做的事)。
  3. 对列表的关键字进行迭代,为每个关键字创建新的 TagElement。
  4. 将标签的名称设置为关键字的值(用 @ 符号开始)。
  5. 最后,为类 Javadoc 向标签列表中添加新的标签。

方法必须返回目标对象。通常和作为目标而传入的是同一个对象。这完成了您的转换扩展的创建和实现。

步骤 5. 测试扩展

既然您已经定义并实现了扩展,那么是时候测试了。创建打开新的运行时工作平台的新的调试配置来进行测试。

  1. 要创建该配置,就在主菜单中选择 Run > Debug
  2. 在对话框中,创建新的 Eclipse 应用程序配置并适当地命名。

提示:
您可以变更工作区的位置,通常好的做法是选择新的位置,从而避免对现有工作区的非故意的影响。

  1. 保留余下的默认设置(图 8)。
图 8. 新建调试配置
New debug configuration 的截屏
New debug configuration 的截屏
  1. 当您完成了配置的编辑之后,单击 Debug 启动 Eclipse 的新实例。该新的实例将拥有您刚创建的,作为插件安装的转换扩展。
  2. 要测试扩展,您需要创建新的 Java 工程,在 Eclipse shell 的新实例中的该工程中创建 UML 模型。
  3. 在 UML 模型中,创建测试包和类,并且包含一些属性或操作。结果的工作区应看起来如图 9。
图 9. 运行时工作平台中的测试工程
运行时工作平台中的测试工程的截屏
运行时工作平台中的测试工程的截屏

接下来,您需要向类中添加关键字,因为您的扩展只能处理定义了关键字的类。

  1. Properties 视图中选择类和 Stereotypes 子选项卡。
  2. Keywords 字段中输入文本(图 10)。
图 10. 设置关键字属性
设置关键字属性的截屏
设置关键字属性的截屏

设置了测试工程和模型之后,现在您需要创建定义 UML-to-Java 5 转换的主参数的新的转换配置。

  1. 在主菜单中选择 File > New
  2. Transformations 类别下,选择 Transformation Configuration,然后单击 Next(图 11。)。
图 11. 创建新的转换配置
创建新的转换配置的截屏
创建新的转换配置的截屏
  1. Rational Software Architect 中包含了许多转换类型。选择 UML-to-Java 5 转换(图 12),因为它是针对您创建的扩展的。
  2. 给它个合适的名称。该名称将用作 Java 工程中的配置的文件名。
图 12. 选择转换
选择转换的截屏
选择转换的截屏
  1. 在转换配置中您需要首先指定的是源模型目标工程
    • 确保选择 UML 模型,因为它出现在 Models 虚拟文件夹之下,而不是实际的 .emx 文件。
    • 通过选择 Java 工程本身选择目标(图 13)。
图 13. 为转换设置源和目标
为转换设置源和目标的截屏
为转换设置源和目标的截屏
  1. 您可以随意地在接下来的配置设置页上关闭 get 和 set 方法的自动生成(图 14),并用其余页面上的其他选项进行试验。然而,对于此简单的测试,单击 Finish 接受默认值。
图 14. 转换配置选项
转换配置选项的截屏
转换配置选项的截屏

既然已经创建了配置,那么就调用它。对于本项目来说,不必再次创建。

  1. 要调用转换及对其的扩展,选择图中的类,调用弹出菜单,并选择 Transform > My UML to Java5 Transform Test.tc > UML to Java V5.0 (图 15)。
图 15. 调用转换
调用转换的截屏
调用转换的截屏

图 16 显示出转换的结果。您可以看到,类的 Javadocs 中包含了与您添加的关键字的值相匹配的 Javadoc 标签。

图 16. 生成的代码的结果
生成的代码的结果的截屏
生成的代码的结果的截屏

结束语

UML-to-Java 5 扩展的这个简单的实例仅仅为了示范创建扩展的基本机制。现实中的扩展可能会更智能,使用模型中的信息,对所生成的代码做出更有趣的变更,或者向源代码中添加伙伴工件。本文的重点是当您想要利用所有的现有工作,并且仅需要对输出进行小变更或做小处理时,对现有的转换创建扩展有很大意义。拥有一个公共的,生成代码的转换,以及其他工件(举例来说,部署描述符或伙伴文件)也简化了开发过程,因为您只需要运行一个转换而不是许多。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=272685
ArticleTitle=使用 Rational Software Architect V7 扩展 UML 到 Java 5 的转换
publish-date=12032007