因此,使用 UML 作为其主要建模方法的很多企业都将其所有工作流捕获为“活动关系图”。不过,业务分析人员社区认为 UML 模型和工具与其需求并不直接相关,因为
UML 模型和工具并未处理一些关于工作流的重要业务问题,如:
近年来,市场上出现了 WebSphere Business Modeler(以下称为 Modeler)之类的专用工具,可满足所有这些业务分析需求。企业并不希望重新输入业务流程,而希望对其现有
UML 活动关系图进行转换,将其作为 Modeler 流程导入。
Rational 平台使用 XMI(模型的 XML 表示形式)捕获 UML 模型。例如,图 1 显示了 Rational Software
Architect 生成的 .emx 文件的可视表示形式。
清单 1 显示了包含 UML 活动关系图的原始 EMX 文件的摘录。请注意 XMI 专用类型,如 uml:Action、uml:ControlFlow、uml:InitialNode、uml:DecisionNode
等,这些都代表活动关系图上的元素。
Modeler 提供了一个 XML 模式,定义了可以作为业务流程随相关构件导入的 XML 文件的结构。此 XML 模式位于 Modeler
安装路径下: samples\import\xml\wbimodeler.xsd。清单
2 显示了用于表示流程流内容的模式的摘要。
清单 2. 用于表示流程流的内容的模式
<xsd:element name="flowContent" minOccurs="0">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="startNode" minOccurs="0">
…
</xsd:element>
<xsd:element name="stopNode" minOccurs="0">
…
</xsd:element>
<xsd:element name="endNode" minOccurs="0">
…
</xsd:element>
<xsd:element name="task" type="Task" minOccurs="0"/>
<xsd:element name="decision" type="Decision" minOccurs="0"/>
<xsd:element name="merge" type="Merge" minOccurs="0"/>
<xsd:element name="fork" type="Fork" minOccurs="0"/>
<xsd:element name="join" type="Join" minOccurs="0"/> |
将 UML XMI 内容映射到 Modeler
XML
因此,如果我们希望从 UML 转换到 Modeler,只需要将 XMI 元素转换为其对应的 Modeler 等效项即可。表 1
显示了我们必须进行转换的各个元素,从而将活动关系图转换为 Modeler 流程。
表 1. UML 到 Modeler 的元素映射
UML 元素或属性 |
Modeler 标记或属性 |
xmi:type="uml:Activity" |
"Process" |
xmi:type="uml:Package" |
"Catalog" |
xmi:type="uml:Class" |
"Service" |
xmi:type="uml:Action" |
"Task" |
xmi:type="uml:ControlFlow" |
"Connection" |
xmi:type="uml:DecisionNode" |
"Decision" |
xmi:type="uml:MergeNode" |
"Merge" |
xmi:type="uml:ForkNode" |
"Fork" |
xmi:type="uml:JoinNode" |
"Join" |
xmi:type="uml:InitialNode" |
"startNode" |
xmi:type="uml:ActivityFinalNode" |
"endNode" |
xmi:id |
Modeler 元素由“name”属性进行标识 |
name |
"description" |
IBM Model Transformation Framework (MTF) 是一组可帮助开发人员在 Eclipse Modeling
Framework (EMF) 模型之间进行转换的工具。通过使用此框架,可以实现上面所述的映射。
通过 MTF,可以使用 MTF 关系定义语言将模型之间的转换作为一组声明规则(也称为关系)加以定义。MTF 转换引擎将随后执行这些规则来将目标模型文件与源模型文件同步。此方法的优势在于,可以非常简洁地定义复杂映射(相对于等效的
Java 代码而言),从而能够快速定义转换原型。MTF 仅适用于 EMF 模型,为了能成功使用,应该对其加以熟悉。
在实现转换前,我们必须标识需要使用的 EMF 模型。在本文中,转换的源是 Rational .emx 文件(UML 模型)。可以使用
Eclipse.org UML2 实现(一个 EMF 模型)读取此模型。
清单 2 中的 XML 模式定义目标文件。我们可以使用 EMF 工具来从 XML 模式生成 EMF 模型,但本例中没有这个必要,因为与模式对应的
EMF 模型包括在 Modeler 工具中。
我们在扩展名为 .rdl 的文本文件中定义转换的规则。此文件扩展名与 MTF 映射规则编辑器关联。文件开始部分是一些 import
语句,告知 MTF 规则所引用的 EMF 模型,如清单 3 中所示。
清单 3. 指定 EMF 模型的 import 语句
import uml "http://www.eclipse.org/uml2/1.0.0/UML"
import bom "http://www.ibm.com/wbim/bomSchema1.0"
import emf "http://www.eclipse.org/emf/2002/Ecore"
import uml "http:///com/ibm/mtf/xtools/uml2.ecore"
import ws "http:///com/ibm/mtf/model/workspace.ecore"
import emf "http:///com/ibm/mtf/model/emf.ecore"
import util “http:///com/ibm/mtf/util.ecore” |
前三个 import 语句分别声明 UML2 模型、Modeler XML 模式和 EMF Ecore 模型。其余 import
引用随 MTF 提供的 EMF 模型,从而提供各种实用工具来简化规则的编写工作。
我们可以基于上面的映射表格快速地定义一些初始规则,如清单 4 中所示:
清单 4. 映射规则
relate activity2process(uml:Activity activity, bom:Process process)
relate pkg2Catalog(uml:Package pkg, bom:Catalog bomCatalog)
relate action(uml:Action action, bom:Task task)
relate connection(uml:ControlFlow flow, bom:Connection conn) |
其中的每个 relate 语句都是规则。可以将每个规则都视为在定义所指示的元素之间的映射(查找表)。对于每个规则,我们现在可以定义一组约束来应用到所映射的元素。MTF
转换引擎将尝试创建或修改目标模型,使其遵循这些约束。
例如,清单 5 中的规则指定只要 UML Action 映射到 Modeler Task,Action 的名称就应该与 Task
的描述相同。另外,还将约束定义为先决条件——Action 仅能在其 XMI ID 与 Task 的名称匹配时才可映射到此 Task。这种类型的先决条件约束对于确保每个
Action 仅映射到一个 Task 非常重要。
清单 5. 用于将 Action 与 Task 相关的规则
relate action(uml:Action action, bom:Task task)
when equals(action.xmi_id, task.name) {
equals(action.name, task.description)
} |
除 equals 外,EMF 还提供了其他几种类型的约束。其中最重要的是,允许将规则链接在一起,以在映射两个元素时将更多规则应用于相关元素。例如,当将
UML Activity 映射到 Modeler Process 时,会希望将 Activity 包含的 Action 映射到
Process 所包含的 Task,如清单 6 中所示:
清单 6. 将 Activity Action 映射到 Process Task
relate activity2process(uml:Activity activity, bom:Process process)
when util:MatchString "{0}##{1}" (activity.package.xmi_id, activity.name, process.name) {
action(over activity.action, over process.flowContent.task),
connection(over activity.edge, over process.flowContent.connection)
} |
清单 6 中的约束将操作和连接规则应用到 UML Activity 和 Modeler Process 的内容。over 关键字指示将处理元素的集合。
编写了一定规则后,可以直接通过创建 MTF Mapping Rules 启动配置(从 Run … 菜单)来执行,也可以在
Java 应用程序或 Eclipse 插件中使用 MTF Java API 来执行。我们实现了一个简单的 Eclipse 插件,可提供弹出菜单来为任何
.emx 文件执行转换。
仔细观察一下清单 1 中的 UML 模型,会发现 XMI 要区分 ID 和名称。例如,操作 Display the invalid
transaction method 的 ID 为 xmi:id=_ Avu8wIUVEdm56dw_R1diwQ。此操作将转换为
Modeler 中名为 _Avu8wIUVEdm56dw_R1diwQ 的活动,其描述为 Display the invalid
transaction method,但此名称在业务流程关系图中并不便于阅读。
因此我们需要使用名称替换 ID,需考虑 Modeler 的名称长度限制为 50 个字符,且在出现重复名称时使用“:1, :2,
3”作为后缀。此步骤要求在 MTF 完成转换后使用 Modeler API 进行后续处理。
为了完成此任务,我们将使用 Modeler 中提供的 com.ibm.btools.te.xml 插件,此插件定义了相关的 Modeler
元模型接口。图 2 显示了此包中的组成部分。
图 2. Modeler 类关系图
MTF 转换的结果是嵌入标准 EMF Resource 对象的 Modeler 业务流程,如清单 7 中所示:
清单 7. 所得到的 Resource 对象
Resource targetResource = set.createResource
(URI .createPlatformResourceURI(target.getFullPath().toString()));
……
/*MTF invocation, transforming original UML model into Modeler resource */
ITransformationSession engine = MappingEngineFactory.createTransformationSession(def);
Object[] args = new Object[] { source, targetResource };
Mapping mapping = engine.map(rule, args, new SubProgressMonitor(monitor, 27)); |
所得到的这个 Resource 对象包括关于 Modeler 业务流程的层次结构信息。由于命名问题无法通过简单的映射加以解决,因此我们直接检索
Resource 对象的内容,然后使用相关的 Modeler 包 API 对其进行操作。
所检索到的第一个对象是DocumentRoot 实例对象,此对象在清单 8 中的操作逻辑中作为根节点使用。
清单 8. DocumentRoot 实例对象
DocumentRootImpl wbmDocRoot= (DocumentRootImpl) targetResource.getContents().get(0);
// Then, using DocumentRoot, retrieve the Processes object.
ModelType modelType = wbmDocRoot.getModel();
ProcessModel pcsModel = modelType.getProcessModel();
ProcessesType pcsType = pcsModel.getProcesses();
EList processes = pcsType.getProcess(); |
然后在清单 9 中,我们将进行进一步的工作,以将各个流作为 FlowContentType 检索,并访问各个嵌入的 Modeler
元素对象: Task, Connection, Decision, Join, Fork and Merge.
清单 9. 检索流
for (Iterator i = processes.iterator();i.hasNext();){
ProcessImpl process = (ProcessImpl)i.next();
FlowContentType flowCType = process.getFlowContent();
EList tasks = flowCType.getTask();
EList connections = flowCType.getConnection();
......
} |
由于已经访问了这些详细元素对象,接下来就可以实现其他必要的逻辑。对于命名问题,我们需要使用更为可读的描述来转换名称,但要将其长度限制为不超过
50 个字符。另外,为了避免相互冲突的重复项,我们将对重复项分配后缀“:1,:2,:3”。为了使用更为可读的描述替换原始 ID
名称并限制长度,我们将访问运行时元素 TaskImpl 对象。
我们将所有更改过的名称存储在名为 nameUpdateMap 的另一个 HashMap 中。此 HashMap 的 Key 为原始名称
(UMLID),而 Value 为其匹配项的最大数量。以 Task 为例,清单 10 显示了解决其重复名称问题的完整逻辑。
清单 10. Task 的重复名称逻辑
private HashMap taskNameMap = new HashMap();
....
// associate task names with a legible description
for (Iterator j = tasks.iterator();j.hasNext();){
TaskImpl task = (TaskImpl)j.next();
String name = task.getName();
// The current name that comes from UML and which is a unique Id.
String desc = task.getDescription();
if (desc!=null && !("").equals(desc)){ // truncate desc length to 50 at most
if (desc.length() > 50) { desc = desc.substring(0,50); }
// verify whether desc already exists and update the max ID value for same Name
iif (taskNameMap.get(desc)== null) {
taskNameMap.put(desc,new Integer(0));
} else { // Update the suffix maximum
Integer maxID = (Integer)taskNameMap.get(desc);
maxID = new Integer(maxID.intValue()+1);
taskNameMap.put(desc,maxID);
desc += maxID.toString();
}
task.setName(desc);
nameUpdateMap.put(name,desc); // Update the names correspondence with the suffixes
}
}
// Then process the nodes to update the names in the model. |
此逻辑也适用于其他节点元素,如 Decision、Fork 或 Merge。接下来需要在转换后的 Modeler 流程中更新
Connection 类型的连接链接,因为 SourceType 和 TargetType 可能会使用更改后的名称链接各个元素。
清单 11 将更新连接,以确保其仍然有效。
清单 11. 确保连接仍然有效
for (Iterator k = connections.iterator();k.hasNext();){
ConnectionImpl connection = (ConnectionImpl)k.next();
SourceType sourceType = connection.getSource();
TargetType targetType = connection.getTarget();
String cp = sourceType.getNode();
if (nameUpdateMap.get(cp)!=null)
{ sourceType.setNode((String)nameUpdateMap.get(cp)); }
cp = targetType.getNode();
if (nameUpdateMap.get(cp)!=null)
{ targetType.setNode((String)nameUpdateMap.get(cp)); }
} |
最后,保存 Modeler Resource,从而在所得到的文件中提供更好的可读性,如图 3 中所示:
图 3. Modeler 中得到的流程
本文中描述的转换可使在 Rational Software Architect UML 环境中建模其流程的用户方便地在 Modeler
环境中重用这些模型。对于现有的 Modeler 到 Rational 的转换,此 Rational 到 Modeler 转换工具的可用性对
Rational 平台与 WebSphere Business Modeler 间的往返业务工程工作可起到促进作用。
此转换还意味着可以针对性能需求(如在吞吐量、处理、加载和资源可用性方面的业务需求)对使用 UML 生成的功能业务体系结构进行验证。
学习
获得产品和技术