本教程向您描述了,怎样扩展
IBM?Rational ?Software Architect 的应用,以及怎样使用您自定义的模板,来自动生成一个设计方案
Rational Software Architect 为您在设计服务型结构(SOA),或其他方案时的联合应用,提供了一些技巧。您也可以通过这些自动操作,来提高方案的质量,以及支持总体管理进程。
在开始之前
思考您想从本篇指导性文章中,学到什么,以及怎样得到这些您想学到的内容。
关于本教程
为了充分利用模型驱动开发 (MDD)带来的便利,您的设计及开发环境需要有以下特性:
最便于可重用的环境:人们可以重用经验证的方案,以解决问题,同样也能为其他可重用提供解决方案。
基于角色的工具:工具应致力于眼前手头的任务,以及人们在任务中发挥的作用(例如,Business Analyst
或者IT Architect)。
过程支持及指导:在背景环境中总有方法及过程支持。
一个可扩展的平台:团队可扩展及自定义环境,以适应他们的需求。
自动操作:框架结构的潜在模型,以及映射允许模型的半自动转换,从高层级到低层级的抽象,并最终转换为可执行代码。从低层级到高层级的抽象也是可能的。
这些就是 IBM? Rational? 软件交付平台,以及 IBM? Rational? Software
Architect 的所有特性。在本系列四篇指导文章中,您可以学到怎样去扩展平台,以及在创建基于 SOA
的方案时,怎样去应用 Rational Software Architect 来帮助我们。此外,我们还解释了什么是模型,以及怎样利用
Rational Software Architect 的可扩展技巧。
第 1 部分 将 SOA 与模型驱动开发联系起来。
第 2 部分 初步完成创建您自己的 UML 概要文件及模型模板。
第 3 部分 在第 2 部分的基础上,快速创建基于模板的工程及模板和转换。
第 4 部分 描述并加工您的软件资源,以便于重用。
在学习完本教程后,您应该在设计 SOA 时,能够随意应用扩展 Rational Software Architect
的技巧。您将知道什么是建模,以及怎样去创建 UML 概要文件、模型模板以及可再用资源。
关于本教程
在本教程中,也即系列的第 3 部分,我们会讨论,怎样在 Rational Software Architect
中,利用我们自定义的转换来自动设计一个 SOA 方案。转换的一个关键方面是,它们能使您进行各种层级的抽象。Rational
Software Architect 提供了您在设计 SOA 方案时,可以应用于排列中的一些技巧。另外,您可利用这些自动操作,来提高方案的质量,并能更好的支持总体管理过程。
在本教程中,您将创建您自己的从模型到文本的转换,以完成指导方针、协定、最佳实践方式以及每次您解决一个特定问题时,都需遵守的基本执行方案。从这样的一种方案中产生的产品,可以是基于文本的任何物,包括代码、脚本、SQL、文件、Eclipse
的资源以及等待。
您在本教程中解决的问题,是正确地创建了一系列的 HTML 文件,并记录了一系列的服务。您应该使用一个共同的主题、格式及内容类别,以及用一种固定的方式创建
HTML。
本教程由从下到上的顺序叙述。有鉴于此,您将从一个模型到文本转换产生的 HTML 文档的例子开始学习,并使用上述产品,作为从模型到文本转换控制过程的输入。
目标
在学完本教程后,您将更好的理解,怎样利用 Rational Software Architect 的工具及技巧,来完成您自己的模型到文本转换。这些自动操作将有助于提高您的团队的效率,提高解决方案的质量,并支持您的管理过程。这些自动操作将您最好的实践方案译成代码,这些代码对您的公司来说,是独一无二的,并是您所在公司的竞争优势的一方面。
在学完本教程后,通过使用 IBM? Rational? Software Modeler 以及 IBM?
Rational? Systems Developer, 或者 Rational Software Architect
V7,您将能够描述,在Rational Software Architec 中构造转换的不同方式,进一步说,您将学到怎样去创建、定义、构造以及测试您自己的模型到文本转换。
您将在本教程中看到,以下将会使用到的产品:
Eclipse Modeling Framework (EMF)产品
应用 Exemplar Authoring 工具的, Eclipse Modeling Framework
Technology (EMFT) Java Emitter Template (JET)项目
基于 HTML 服务详细说明书报告
前提条件
为了更好地学习本教程,建议您去熟悉以下工具:
Eclipse, 开放代码集成开发环境(IDE)或者 Rational Software Architect,
Rational Systems Developer, 或者 Rational Software Modeler
Java? Standard Edition
XML,即 Extensible Markup Language
XPath,即一种查询 XML 文件的途径
熟悉以下内容,将有助于您理解本教程,但不是必需的:
UML,即 Unified Modeling Language
SOA,即 Service-Oriented Architecture
EMF,即 Eclipse Modeling Framework
Eclipse 插件开发
EMF, UML, 以及 API 扩展性
浏览 参考资源,寻找有用链接,以获得关于本问题的更多信息。
系统需求
为完成本教程,您需要安装以下所述的软件(浏览 参考资源 寻找到试用版本的链接):
Rational Software Architect V7.0
或者
Rational Software Modeler V7.0
或者
Rational Systems Developer V7.0
检查工作场景并做好工作区准备
在“使用 Rational Software Architect 设计 SOA 服务”系列文章中(参见
参考资料),我们讨论了,怎样使用模型完成一个基于 SOA 方案的设计。我们能够在不同的抽象层级下工作,并按此种方式使用一些模型元素。这些模型元素有助于在设计中指导我们,同时能使我们根据需要产生具体的产品。
布置
在本教程中,我们学习了设计 SOA 方案(以及其他)可得到的潜在支持。在第 1 部分中,我们学习了 Rational
Software Architect 支持的两类产品,即 UML 概要文件及模型模板。在第 2 部分中,我们学习了基于模板的工程,以及怎样在
Rational Software Architect 中创建模板执行方案。
在本教程中,我们将要学到一种具体的转换,也就是从模型到文本的转换。通过使用包含在模型中的信息,您将创建一个将模型作为输入的转换,产生
Eclipse 产品,包括 Eclipse 项目、文件夹及文档。
工作场景综述
当使用 UML 模型时,我们通常希望,使用模型能够达到以下四个目标:
通过使用标准符号与他人交流设计方案
在执行之前通过设计使用工具及技巧
使用模型以产生其他需要的产品(例如更具体的模型、代码、测试脚本、开发脚本以及文件)
通过使用 Eclipse Modeling Framework Technology (EMFT) 及
Java Emitter Template (JET),提供一个能与转换联合应用的用户友好的界面。
对于本教程,我们假设,您正为眼前的一个问题寻找解决方案,该问题就是,怎样创建一系列的 HTML 文档,来记录由
Software Services 模型定义的一系列服务。我们已经创建了此类的一系列文档,它同时也是我们的模型到文档转换要产生的文档的例子。这系列的文档叫做一个例子。对于本教程而言,它就是是假设的前提条件。
您(转换调试者)将学到工具是怎样使范例的,以及怎样创建 EMFT JET 转换的普遍操作。
注意:
人们感兴趣的是,工具使用一次 EMFT JET 转换,来完成我们想要建立的 EMFT JET 转换的第一步。
在一个高层级上,EMFT JET 转换包括以下部分:
一系列相当于转换所要产生的产品的模板
一系列用于控制转换的进程及工作的模板
一个包含转换所需输入信息的模型,转换需要此模型。
注意:
在本例中您构建的输入模型,并不是一个终端用户会创建,并用作输入的模型所必需的。终端用户模型将包含,关于模型用于转换输入的更多信息。在本指导系列的第
4 部分,您将会看到,怎样将一个用户模型,转化成一个能被 EMFT JET 转换识别的输入模型。
如果您将一次 EMFT JET 转换中的部件,与著名的 Model-View-Controller
样式联系起来,您可以想到把产品当作 View 的样式,将进程驱动当作 Controller 的样式,以及将模型当作
Model 的样式,如图 1 所示 。
图1. Model,Controller,以及
View 之间的相互关系
如上所述,您用于创建模型的一个附加部分是范例。 包含范例的本系列产品,是我们最佳实践方案的代表。这是构建转换时,您所使用开始部分的产品。
当创建 EMFT JET 转换 (或“转换”)时,您要先考虑到,用户将向转换提供什么信息这个问题。而且,您要将注意力放在,描述一个输入模型上,该模型将模板创建简化过程进行优化,并准确包含了模板所需的信息,准确的意思就是不多也不少。
当您构思完 EMFT JET 转换后,您要为您的解决方案,向 EMFT JET 转换中优化的、自定义的模型,计划一个所需的用户模型
(在本例中,也即 Software Services 模型) 。我们在本系列文章的第 4 部分,涉及到了映射转换,并在图
2 中显示了转换与 EMFT JET 转换之间的关系。
图 2. 映射转换与 EMFT JET 转换之间的关系
步骤概述
在本部分中,您将通过完成以下步骤,来创建一个基于 EMFT JET 的模型到文档转换 :
为您的工作区域做好前期准备您将引入一个包含范例的所需输入模型。
评估范例:在本步中,您将评估与范例相联系的产品。
创建转换项目:下一步,您将创建一个使用 Exemplar Authoring 技巧的新的转换项目
描述产生了哪个产品:为了完成这一步,您需要分析范例,以决定哪一个模板需要同转换一起被构建。作为这个工作的一部分,您也可以从预测转换输入模型的部件及结构开始。
构建转换模板当您已决定需要哪一个模板,并对输入模型有了较成熟的想法,您就可以为转换创建一个模板。然后您可以用输入模型的动态参考部分代替模板的静态方面。
测试转换:在您已完成转换以后,您可以对它进行测试。
为您的工作区做好前期准备
在开始使用 Rational Software Architect 时,您可以装载一个,包含与范例相联系产品的项目。正如现在您所知,我们希望范例能成为最佳实践方案,并包含了预计会在需要完成的产品中遇到的所有变量。
第一步,您需要启动 Rational Software Architect ,并创建一个新的工作区:
启动 Rational Software Architect,在 Workspace Launcher
对话框中, 通过输入名字 MDD-PBE-Part3-workspace 来定位工作区。然后点击 OK。
关闭欢迎界面,现在要载入包含范例的项目。记住,范例就是您希望模型到文本转换,所要产生产品的代表例子。
使用 Import from Project Interchange 向导,以载入这个文档中所有的项目:
ServiceSpecification-ExemplarAnalysis.zip
概括载入的项目:
范例包含于单个项目中: TravelPlannerService Specification Report。它包含了描述特定服务的一些
HTML 文档,也包括了那些页面用到的一些文档 。范例不仅仅只包括 HTML 文档,它同时还含有包含这些
HTML 文档的 Eclipse 项目 。在本例中,我们想要我们的模型到文本转换创建一个新的项目,以及一些相应的
HTML 文档。
有一个 Snippets 项目包含了,在转换控制过程中您将使用到的 JET 片段。
最后,有一个名为 Sandbox 的项目,它包含了稍后将会在工作中使用的 XML 文档。
评估范例
下一步,您需要观察组成范例的产品 (项目、文件夹以及文档) 。目标是对执行过程有充分了解,并知道一个主题事项的专家,是怎样创建另外一个范例的。理想条件下,要么您就是一个主题事项专家,要么在创建及分析范例时,您曾咨询过专家。本练习背后所做的假设是,需要创建一系列的(在本例中)
HTML 文件项目,来与一系列的建模服务相同步,在每一个情况下,创建的文档都要坚持一些惯例及内容。您将建立的模型到文本转换,将记录下这些惯例及说明,并自动创建一系列服从那些规则的产品
问题是:本范例展示的那些规则是什么?为了弄清楚那些规则,您需要回顾一下 TravelPlanner Service
Specification Report 项目的内容。 这些文档(以及该项目本身)将举例说明,您创建的转换必需产生的
Eclipse 产品。
首先,查看 main.html 文件, 您可以通过和 System 编辑器一起,在 Eclipse 中打开它,以在浏览器中打开这个文件。
图 3. main.html 文件
页面列出了三种服务(旅行, 空中旅游, 付费), 它们中的每一个,都可以与相应的 HTML 页面相链接。
当您点击 Trip 链接时,您将会看到一个代表性规格页面(如图 1 所示)。
图 4. 规格页面
注意这个特定的服务有三种操作,其中它们中的每一个,都有任意数量的输入值及返回值。每一个操作也有描述该操作具体行为的文本。
您同样可注意到,在页面上有一处通用的记录服务自身文件的地方,尽管此服务看起来并没有如此相关信息。
在范例项目中,查看剩余的文件,您将会在 Theme 文件夹下看到一些主题文件。如上所述,同样也有每一个
Eclipse 项目需要的项目自身及 .project 文件。
在此处,您可以描述一下需要得到什么产品,以及需要什么规则来管理他们的内容。
创建转换项目
既然我们对范例已有一定理解,现在就为转换创建一个项目。开始时,您可以创建初始的模型到文本转换执行方案的框架。在创建项目后,您就可以使用范例管理工具,来添加需要的模板。
通过点击 File > New > Project 来打开新资源向导(图 5)。
图 5. 启动向导
选择 EMFT JET Project with Exemplar Authoring 向导 (图 6)
,然后点击Next。
图 6. 新项目界面
在 “Project name” 区域,输入 com.ibm.serviceSpec.report.xform
(图 7)。这个值既是包含转换执行方案的项目的名字,又是当参考转换时使用到的转换的 ID ,它要么在 Run
对话框下,要么在其他的转换里。
然后点击Next。
图 7. 用范例管理创建一个新的 JET
项目
在下一个页面中 (图 8), 选择项目或包含范例的项目。在本教程中,仅仅有一个项目,TravelPlannerService
Specification Report,它就包含了范例。
图 8. 转换范围页面
点击 Finish。范例管理工具将为转换 Schema 页面打开(图 9)。
图 9. 转换 Schema 视图
在编辑器的左边,是一个范例项目的文件系统视图,您将描述转换怎样创建这些产品 (项目、文件夹以及文件)。描述部分将在编辑器的右边被创建出来。
右边部分将显示两种不同系列的信息:
首先,转换的输入模型的工作场景,将以一种自由的格式呈现出来。初始的模型有一个名为“root”的单个模型类别。您可以在接下来的步骤中添加更多的模型类别。
它同样展示了,每一个模型类别的一个例子的操作。这些操作将会创建项目、文件夹以及文件,并且它们同样可以定义模型的新属性。
描述产品
在本步中,开始描述规则,这些规则管理着需要产生那些产品,以及需要为转换产生多少每一类的产品。管理那些产品内容的规则,将在下一步中涉及到。
规则根据输入模型工作场景得到具体化,该工作场景描述了模型到文本转换中,输入的数据模型的结构,对于每一个模型元素类别的例子,您都可以对其创建产品,从而进行
Create Action 操作。
一对一产品
通过为整个范例起一个一词或两词的名字,开始定义输入模型工作场景。例如,使用 serviceGroup,
因为您会在一个单组中定义一些服务。您可以在此期间获得二级模型类别名字。在这种情况下,使用serviceGroup作为类别的名字。
在右边的节点处选择root,右键点击,然后选择 New>Type。
图 10. 从根节点处创建一个新类别
输入 serviceGroup 以代替默认的新类别名字。
图 11. 在根节点下重命名节点
这意味了以下内容:
首先,在输入模型中,可能有许多 serviceGroup 类的例子,并且转换会为每一个例子,产生一个单独的
HTML 项目。
第二,产生一个 HTML 项目所需的所有信息,要么由 serviceGroup 元素自身提供,要么由位于
serviceGroup 元素上的元素提供。
为每一个 serviceGroup 元素产生的 Eclipse 产品,是一个 Eclipse 项目。
点击左边代表TravelPlanner Service Specification Repor的节点,然后将其拖动到serviceGroup节点。
图 12. 打开报告文件夹,进入 serviceGroup
这个拖拉操作会引发 serviceGroup 节点的一次 Create Project 操作。该操作将项目创建到,所有其他产品被创建的地方。通过在serviceGroup
节点上进行 Create Project 操作,您可以在转换的输入模型上指定,为 serviceGroup
类别的每一个例子创建一个项目。
打开 Properties 视图,以查看新操作的属性。
图 13. Properties 视图
名为*name的操作参数显示,该操作将会一直创建一个名为 TravelPlanner Service Specification
Report 的项目。考虑到每一代产品的名字都会发生变化,您需要对其做出改变,并且这种改变需要基于输入模型而做出。
作为一个通行的规则,产品名字需要两个属性。第一个是在产生产品时,包含了使用名字的获得属性 。名字通常来源于一系列的命名习惯,如从输入模型那里起一个更小、更简单的含相关信息的名字。
创建一个获得属性
在这种情况下,您可以创建一个名为projectName的获得属性,以作为项目的全名,然后将另一个名为name的属性具体化,那将在输入模型中可见到。
从创建名字属性开始:
选择 serviceGroup 类别,然后右键点击并选择New > Attribute。输入projectName以作为属性的名字,取代
newAttribute 的默认值。
图 14. 选择 serviceGroup
类别
接下来,定义获得属性,选择Create Project操作。然后,在 Properties 视图下,选择整个*name参数值
(如图 15 所示)。
右键点击,然后选择 Replace with Model Reference。
图 15. 选择 Property and
Value 列下的一整行
用作项目名的属性 (projectName)在目前尚未定义。选择 serviceGroup,然后点击New按钮(图
16)。
图 16. 选择 serviceGroup
作为模型参考
当您看到 Create New Derived Attribute 对话框 (图 17)时,在第一个区域输入属性名:projectName。
图 17. Create New Derived
Attribute 对话框
最后的区域,是您可以以获得属性值的方式赋值的地方,现在,该值是一个常量,但是要使名字中的第一个字母与属性
name的值相同。
选择 TravelPlanner 排列在 Calculation 区域内,然后点击 Insert Model
Reference 按钮。
当 Select Model Reference 对话框显示当前的模型时,选择 name 属性,然后点击
OK。
图 18. 选择 Mode Reference
对话框界面
Create New Derived Attribute 对话框 (图 19)会显示,serviceGroup
元素属性 “name”的值会与 Service Specification Report 联系起来,以获得项目名字。这个值将会在这个获得属性中,输入到模型中,并可以被任何一个需要访问此新项目名字的模板引用。因为该获得属性被放在
serviceGroup 类别中,您可以为每一个serviceGroup 元素保留一个独特的、精确的项目名字。
图 19. 创建 New Derived
Attribute 对话框
点击 OK 以回到第一个 Replace with Model References 对话框。 注意,现在出现在列表中的获得属性
projectName ,现在作为一个属性,可以被引用 (图 20)。
选择 projectName 属性,然后点击 OK。
图 20. Replace with Model
References 对话框
注意 Create Project 操作在 name property 区有一个新值,那个属性现在是 serviceGroup
元素的 projectName 属性的一个参考(图 21)。
图 21. Properties 视图
既然您已经为每组服务都设定了一个名字,并且这个名字可用作获得 Eclipse 项目的名字,现在您就需要设定用什么去产生那个项目。
下一步,您需要为每一个 serviceGroup识别出,只出现一次的文件。在本例中,有五个文件符合这条标准。您可以将
Create File 操作,与每一个属于serviceGroup 模型类别的五个文件联系起来 (图 22):
一个 blue.htpl(在theme文件夹中)
Blue.css (在theme文件夹中)
Logo_blue.gif (在theme文件夹中)
.project
main.html
图 22. Schema 视图
每次一个,将这五个文件中每一个都拖到节点 serviceGroup 的顶部 (图 23)。
图 23. 将文件拖到节点 serviceGroup
之上
选择 Create File: .project 操作,然后查看 Properties 视图
图 24. Properties 视图
对于 *path 属性,选择 TravelPlanner Service Specification Report条,右键点击,然后选择
Replace with Model Reference(图 25)。
图 25. 用模型参考值代替 *path
值
在 Replace with Model References 对话框下,如果它还没被选中,就选择projectName属性。(图
26)。
图 26. Replace with Model
References 对话框
点击OK。
Properties 视图 (图 27) 现在应该显示,在创建转换的项目中,创建文件的 *path 名字应该是
.project 文件。
图 27. 更新 Properties 视图
为另外四个 Create File 操作重复更新 *path 属性值。注意到,在每一个Create File:
logo_blue.gif操作中,您将需要更新 *target 属性,因为二进制文件没有 *path 属性。
一对多产品
剩余的三个文件用 HTML 页面,代表范例中的三种服务。不像其他的文件,每一个转换的声明,基于在输入模型中描述过的服务的数目,将会产生不同数目的这类文件。而且,不像其他文件,这三个文件有相同的结构,并且能够用相同的模板产生出来。
这是一对多关系(一个 serviceGroup 有许多的服务说明页面),需要向输入模型添加另外的类别。该类别将位于serviceGroup
类别之中,并且包括所有产生与单个服务相关的内容所需要的信息。
选择 serviceGroup 节点,右键点击并选择 New > Type。称这个新的节点为 service(图
28)。
图 28. 创建一个名为“service”的新类别
拖拉 Trip_spec.html 文件到 service 类别节点上(图 29)。
图 29. 位于“service”类别之下的
Trip_spec.html 文件
注意:
您可以拖动三个 HTML 文件中的任何一个,但是您关于拖动哪个文件的选择是非常重要的。您所选择文件的内容,将用作创建此类文件模板的初始内容。因此,选择一个更好展示文件变量的文件是很重要的,这些文件就是您稍后需要建立的。在这种情况下,您可能要选择一个能描述三种操作的
HTML 文件,而不是不描述或仅描述一种操作的文件。
注意新操作Create File: Trip_spec.html 的 Properties 视图(图 30)。不仅仅是每一个
HTML 文件的项目名字(在*path属性中)需要被设为变量 ,文件名本身也必须设为可变的 。
图 30. Properties 视图中的新操作Create
File: Trip_spec.html
因为文件名取决于服务名,反过来,这将提供给输入模型,创建一个名为 name 的新属性,为 service
类别(图 31)。
图 31. 在名为“service”的类别下名为“name”的新属性
该获得属性用于产生路径的文件名。
图 32. 创建 New Derived
Attribute 对话框
与您对其他文件做的操作类似,在 Action Parameters 之下,更新 *path 属性的左部,以使用
projectName 属性。
*path 属性看起来应该像这样(图 33):
{$serviceGroup/@projectName}/{$service/@htmlFileName}
图 33. 改变 *path 属性
然后输入工作场景看起来像图 34。
图34. Schema 对话框
总结:
转换在模型中为每一个serviceGroup 元素,创建一个项目及五个单显文件。
另外,转换将会产生多个 HTML 详细说明书,serviceGroup 中每一个服务部分都产生一个。
到目前为止,该模型非常简单,但是仍然有可供添加的类别及属性。我们只关心哪一个 Eclipse 产品被创建,而不关心它的内容。
如果您把类别和属性当作 XML 文件中的元素, 您可以得到一个像表 1 所示那样的结构。
列表 1. 类别和元素的结构
<root> <serviceGroup name="" > <service name="" /> <service name="" /> <service name="" /> </serviceGroup> |
创建转换模板
在这一步中,您会使用 Exemplar Authoring 工具,为模型到文本转换产生的每种文件创建模板。每一个模板的初始内容,都是原来相关文件的内容,这些文件在Exemplar
Authoring 工具中从左边拖到右边。因为大多数内容需要设置成动态的,您就需用 JET 标签标明静态的部分。
每一个 Create File 操作,都需要一个对该操作唯一的模板。您可以使用 Exemplar Authoring工具来产生那些模板,以及一些指示转换逻辑结构的高级模板。
改变初始模板
在 Exemplar Authoring 编辑器的右边右键点击 (图 35), 然后选择 Update
Project。这将会使模板转化为转换项目。
图 35. Exemplar Authoring
工具
在转念项目中展开新创建模板文件夹(com.ibm.serviceSpec.report.xform)以查看被创建的八个模板。这些模板中的一个,logo_blue.gif,实际上是一个二进制
GIF 文件 (图 36) ,它会自动复制到新项目中。
图 36. serviceGroup 模板
使用 JET Template Editor 以打开 project.jet 模板。在该模板中仅有一串
,即 TravelPlanner Service Specification Report, 它应该被设为变量,这样
.project 文件就能顺利产生了。
选择那个文本,右键点击,并选择Find/Replace with JET Model Reference(图
37)。
图 37. 找到并更改 TravelPlanner
Service Specification Report
您可能回想到,有一个新项目名字,在 serviceGroup 类的 projectName 属性中作为项目名的值。
在 Find/Replace with Model References 对话框下(图 38), 选择
projectName 属性,然后点击 Replace。
图 38. Find/Replace with
Model References 对话框
工具用一个 JET 标签代替了选择的文本,该标签在 serviceGroup 上记录了属性 projectName
的值(图 39)。
现在点击Close在 Find/Replace 对话框下。
图 39. JET 模板编辑器中的 project.jet
为 project.jet 模板保持并关闭 JET 模板编辑器。
在 JET 模板编辑器中打开main.html.jet。有几个需要被 JET 标签代替的串。
在题目中用serviceGroup 类别的属性名(图 41)来代替 TravelPlanner
(图 40)。
图 40. JET 模板编辑器中的 main.html.jet
模板
图 41. 用 serviceGroup
类别的名字来代替 TravelPlanner
用一个 <f:formatNow> 标签(图 42)来代替主体中的生成日期。如图 43 所示。
图 42. 生成日期标签
图 43. 用<f:formatNow>标签代替生成日期
提示:
注意在 serviceGroup 的每一个服务中都有一个位置标签。
图 44. 每一个服务的 HTML 的位置标签
在线周围包含了,能链接到带有一个迭代标签的 Trip_spec.html
页面,移除另外的两处链接(参见图 45):
<c:iterate select="$serviceGroup/service" var="service"> <p><a href="Trip_spec.html">Trip</a></p> </c:iterate> |
图 45. 迭代标签
这将有一个效果,既为每个服务做一个链接,链接到到硬编码 Trip_spec.html 的页面。
为了产生一个链接到转换实际创建的页面,移除掉 Trip_spec.html 串,使用写有服务的值 htmlFileName
的 JET 标签(图 46), 然后用服务的名字代替 Trip(如图 47 所示):
<c:getselect="$service/@name"/> |
图 46. 用 HTML 文件名的值代替
Trip_spec.html
图 47. 用服务的名字代替 Trip
保存并关闭 main.html.jet 模板的 JET 模板编辑器。
serviceGroup 文件夹中的其他模板,不需要被编辑,因为它们不包括任何动态内容。
在 JET 模板编辑器中打开 Trip_spec.html 模板,然后在题目中用一个 JET 标签来代替
Trip串,该 JET 标签指明了服务元素的属性名(图 49)。
图 48. 题目标签中的 Trip 串
图 49. 服务部分的 Name 属性
在页面的主体部分做相同的移除(图 50)。
图 50. 页面主体内容
使用 <f:formatNow> 标签去写当前的日期,如图 51 所示。
图 51. 插入当前日期的标签
保存文档。
再次访问输入模型
主体内容的下一部分是一个重复段: 服务中每一项操作的 HTML 代码段,如图 52 所示。
图 52. 3 段 HTML 代码
因为有一些重复每项服务次数的动态内容,您需要添加一个新的位于 service 之中的类,来传递重复的信息。这些信息包括操作的名字,操作的描述,操作的返回值,以及操作内容重复的名字类别值。另外,类别可被排列。
提示:
如果您已关闭了 Exemplar Authoring 工具,您可以在任何时候,通过双击您的转换项目中的transform.tma文件来打开它。
返回到 Exemplar Authoring 工具,来添加这些额外的类和属性:
operation documentation name argument name scalar type returns scalar type |
图 53. 添加的类别与属性
使用Update Project操作来改变 main.jet 模板。您对其他已存在模板所作的改变将被保存。
继续编辑模板
返回到Trip_spec.html模板编辑器,并再次定位到三段 HTML 代码处,每个操作一个。
在 HTML 的第 3 部分周围添加一个<c:iterate>标签 (该段描述了移除 Traveler
的操作)。如图 54 所示。
移除另两段 HTML。
图 54. 添加一个<c:iterate>
标签
移除操作名(removeTraveler) 替换成参考于操作属性name的 JET 模型(图 55)。
图 55. 移除操作名
在同一线段的末端 (在最后一个冒号之后),是代表操作返回值的类别的串。对于移除 Traveler 操作,那个类是TravelerID
[*],那意味着一些类TravelerID将会被返回。您可以简单地写出类TravelerID,在那些带有条件
的属性处,JET 标签会显示为[*],如果标量属性不是 1。这种途径不仅仅将模板变得更加复杂,如果您想编辑那些类,您每次还不得不精确地复制一系列的标签。
在这种条件下,为返回类创建另一个获得属性是更明智的。称这个获得属性为declaration,它将包含了服务返回值的确切声明类别,并且该获得属性可从类及标量属性处获得。
选择包含了服务返回类别的文本,然后右键点击并选择Find/Replace with JET Model
Reference(图 56)。
图 56. 用 JET 模型参考替换服务返回类别
选择返回类别并点击 New(图 57)。
图 57. Find/Replace with
Model References 视图
输入 declaration 以作为获得属性的名字,用对属性type的一个参考来替换 Calculation
,然后点击OK(图 58)。
图 58. Create New Derived
Attribute 视图
最后,用新获得属性的一个参考值,来代替目前的选择文本(图 59)。
在 Find/Replace with Model References 对话框下取消 Whole Word
单选框的选择,然后点击 Replace。
点击 Close。
图 59. 用对新获得属性的一个参考替换文本
默认条件下, Find/Replace 操作会插在一个 XPath 表达行中:$returns/@declaration。但是,在模板的这个点上,没有$returns的当前值,只有$operation的当前值。
因此,您必须按描述的那样,在 returns 上定义新属性,但是,您必须把 XPath 表达行修改为 $operation/returns/@declaration以访问那个值。
每一个操作的问题列都包含了可变数量的问题。在第二个问题附近的圆括号内插入一个标签
:
(traveler : TravelerID [*]): <c:iterate select="$operation/argument" var="argument" delimiter=" , "> |
去掉第一问题(trip: String)以及逗号 (见于图 60)。
图 60. 定义新属性
注意定界符属性的使用,该条件下,在除最后一个以外的每个重复之后,添加一个逗号。
不要忘记关闭 <c:iterate> 标签(图 61)。
图 61. 关闭重复标签的提醒
用对属性 name 的一个参考来替换问题名,该属性位于类别 argument 之上(图 62)。
图 62. 替换问题名
创建一个名为 declaration 的获得属性,在元素 argument之上(图 63)(就像上面您对返回类别的操作一样)。
图 63. 创建一个名为 “declaration”的获得属性
用一个对新获得属性的参考值来替换argument类别:
elect="$argrument/@name"/>: <c:get select="$argument/@declaration"/></c:iterate>): |
在 Find/Replace with Model References 对话框下取消Whole Word单选框的选择,点击Replace,
然后点击Close。
通过用类别operation中属性documentation的一个参考值替换描述操作的文本,来完成操作的模板段(图
64):
<c:get select="$operation/@documentation"/> |
图 64. 操作类别文件属性的参考
对这个模板所作的最后一次改变,是用在名为documentation的服务类别上的新属性的一个参考值,来替换服务的文件。
返回到 Exemplar Authoring 编辑器中,添加一个名为documentation的新属性到service类别中
(见于图 65):
<c:get select="$service/@documentation"/> |
保持前面的操作,然后使用 Update Project 来复制改变。您可能也需要关闭编辑器,然后再打开它。
图 65. 向服务类别添加一个名为声明的属性
关闭 Trip_spec.html 模板编辑器
更改 Main.jet 文件
main.jet 模板就是控制所有转变行为的模板。到目前为止,您使用过的一些模板标签,已根据文件内容做了一些假设。因此,您需要确保预期的元素已插入模板中。
当您使用Exemplar Authoring 工具中的 Update Project 操作时, main.jet
模板已用贯穿整个模型的逻辑结构,对模型进行了改变。退出点是可用的,所以您可以插入特定的逻辑,以防止模型中的特定元素丢失。只要您在评论的开始及结尾部分,插入您的逻辑,那么逻辑将会保持在随后的
Update Project 操作中:
在Exemplar Authoring 工具中使用Update Project操作。
在 JET 模板编辑器中打开main.jet模板(不是 main.html.jet)。
从添加逻辑开始,查看是否向每一个service元素提供了一个文件属性。如果有一个丢失了。使用<c:set>标签以添加一个默认的变量。这个改变需要在$service
(1)段中完成 (列表 2)。
提示:
这些代码段位于 Snippets 项目中
有可供添加逻辑及变量声明的多个段落。注意在每一个元素声明的插入部分内,有一个数量指示符。确保您在合适的位置上添加了代码。
列表 2. 需求说明
<%-- begin custom variables for $service (1) --%> <c:if test="not ($service/@documentation)"> <c:set select="$service" name="documentation" >No documentation provided</c:set> <c:/if> <%-- end custom variables for $service (1) --%> |
注意 XPath 表达使用嵌套的 XPath 表达式$service/@documentation,以用documentation的名字返回一系列属性节点。该表被转化成
Boolean 值,如果列表非空则返回 True,如果列表为空则返回 False 。功能not()否定了那个值并返回了测试值。通过这种方式,如果没有名为文件的属性,则
XPath 表达行返回 True ,该属性目前位于与可变名字服务联系的模型元素上。
为操作元素添加相似的逻辑,以创建一个默认的文件属性(列表 3)。也需检查以发现是否有一个默认的returns元素需要被创建。这个修改操作需要在$operation
(1)段中完成。
列表 3. 需求说明
Authors to insert code here Authors to insert code here Authors to insert code here |
添加逻辑,以测试问题元素上标量属性的值(列表 4)。如果标量值是1,那么问题类就真是一个排列,并且串[*]需要来连接到特定类别的末端。这个修改需要在$argument
(2)段中完成。
列表 4. 需求说明
Authors to insert code here Authors to insert code here Authors to insert code here |
同样的,测试返回元素上标量属性的值(列表 5)。这个修改需要在 $returns
(2) 段中完成。
列表 5. 需求说明
Authors to insert code here Authors to insert code here Authors to insert code here |
最后, 去掉位于 main.jet template 末端的<ws:file>标签:
<%-- Begin: final custom actions --%> <%-- End: final custom actions --%> |
您已完成了对转换模板的编辑。
保存并关闭模板。
测试转换
在最后一步,您将要设置您刚创建的模型到文本转换的执行。然后您可以用一个测试的 XML 输入模型,来测试那个转换。
注意:
在Sandbox项目中有一些样本转换输入模型。
选择orderPlatform.xml然后选择Run As > Input for JET transformation。如果您没有在导航视图下看见菜单项,就切换到
Java?视图下。
浏览并选择Transformation ID,并点击OK(图 66)。
图 66. orderPlatform.xml
的属性
从图 67 显示的输入模型中,转换将产生的页面将显示在图 68 中。
图 67. 输入模型
图 68. 产生的页面
main.html 如图 69 显示。
图 69. main.html 中的页面
Service Specific 页面看起来像图 70。
图 70. Service Specification
页面示例
调试一个转换的方法
如果您没有看到这些结果,这些是调试一个转换的典型步骤:
在 上一部分 的结尾,除去 <ws:file>标签。该标签导致整个模型(包括初始输入模型,以及这个
EMFT JET 转换对其所作的所有改变)被写进文件中。因为在转换开始创建文件之后,模型没有做出任何改变,您通过查看这个dump.xml
文件,可以看到被那些产生文件的模板使用到的确切模型。如果您想看到模型的剩余部分,像这样添加一个标签:
<ws:file template="templates/dump.jet" path="Debug/dump.xml"/> |
在路径属性中的 Debug 应该是工作区一个已存在项目的名字。模板属性参考于 dump.jet 模板,该模板应该仍然在转换模板目录之中。
另一个技术涉及到 <c:get> 或者 <c:dump> 的使用,以写入一个模板节点属性、内容或二级目录的值。您可以向产生的文件中直接输入值
。结果文件可能有语法错误,但是它们将是暂时的。您也可以使用在 <c:log> 标签内的那些标签,以写入模型数据以及调试信息。
总结
在本教程中,我们学习了 Rational Software Architect 以不同方式,让您掌握并应用,解决您公司面临问题的最佳实践方案。特别是,我们以一种从下到上的方式,构建了模型到文本转换。我们用于构建转换的技术包括
EMFT JET,以及 Rational 建模平台的 Exemplar Authoring 技巧。
尽管我们只学习了,产生了一系列 HTML 文件的简单例子,但是,您在本教程中学到的,很容易用到其他实例中去。因此,在学习本教程后您应该知道,怎样将这些技巧,应用到
Java 文件、数据库脚本、调试脚本及其他形式的文件中。
使用并掌握这种方法的困难点在于,您要有合适的范例。伴随解决一个问题最佳方案的是,在创建基于样式工程产品中的困难面。因此,我们鼓励您去总结,存在于您工作环境的产品:最佳实践方案、代码库、书籍、产品、文章以及诸如此类的其他产品。另外,花一定时间和您周围的专家讨论,您平常遇到的一些问题,以及通常做的工作。这些信息将为您使用并掌握模板提供很有力的帮助。
接下来,本系列文章的第 4 部分,您将学习,通过使用 Rational 建模平台的模型映射能力,来构建一个模型到模型的转换。这将可以让您使用一个
Software Services Profile 标记的 UML 模型,来充当转换的输入部分,该转变就是您在本系列部分所完成的。 |