MTF釋疑
MTF是IBM開發(fā)的一個模型轉(zhuǎn)換工具。它是一個Eclipse插件,可以直接在Eclipse平臺上使用,也可以以Java包的形式在Java語言中使用。它的大部分功能要基于EMF和UML2這兩個Eclipse插件。
MTF是模型轉(zhuǎn)換工具,主要用來在模型之間進行轉(zhuǎn)換,例如從UML模型到EMF模型的轉(zhuǎn)換,或者從UML到XSD之間的轉(zhuǎn)換。因為代碼生成也算是一種模型轉(zhuǎn)換,所以MTF也可以用于一些代碼的生成,例如從EMF到Html的生成,或者從JDT(Java development tool)模型到UML模型的反向工程。
MTF中的映射(Mapping)
MTF中最重要的兩個概念就是映射(Mapping)和和解(Reconciliation),它們是整個MTF的基礎(chǔ)。
關(guān)于映射,MTF的幫助文檔中是這么寫的:An MTF rule – a mapping rule – defines a set of constraints to be checked across one or more objects. If the constraints hold, then the objects comply with the rule and don't need to be changed. Rules are checked within a mapping session, which tracks which rules should hold for which objects. It does this by creating objects called mappings; each mapping records that a rule has been applied to some particular objects, and if any of the rule constraints are violated.
一個MTF規(guī)則――或者叫映射規(guī)則,定義了一組約束,用來約束一個或者更多的對象。如果約束能夠保持,那么遵守這些約束的的對象就不需要被改變。規(guī)則在映射組中被檢測,映射組能夠跟蹤哪條規(guī)則應(yīng)該被哪些對象遵守。映射組通過創(chuàng)建叫做映射的對象來完成這件事。每個映射對象記錄了一條規(guī)則被應(yīng)用于一些特殊的對象,以及是否有規(guī)則的約束被違背了。
為了理解這些冠冕堂皇的話語,還是讓我們來看看一個簡單的例子吧,例子來源于MTF自帶的tutorial的example2:
import ecore "http://www.eclipse.org/emf/2002/Ecore"
import emf "http:///com/ibm/mtf/model/emf.ecore"
import ws "http:///com/ibm/mtf/model/workspace.ecore"
relate sample2(ws:IFile file1, ws:IFile file2)
{
mapPackages(over file1.resource.contents, over file2.resource.contents)
}
relate mapPackages(ecore:EPackage pkg1, ecore:EPackage pkg2 )
{
equals(pkg1.name, pkg2.name ),
ordered mapPackages( over pkg1.eSubpackages, over pkg2.eSubpackages)
}
上面例子的作用是,定義從一個EMF模型文件file1到另一個EMF模型文件file2之間的轉(zhuǎn)換規(guī)則。我們先看其中的兩條語句:
relate sample2(ws:IFile file1, ws:IFile file2)
relate mapPackages(ecore:EPackage pkg1, ecore:EPackage pkg2 )
這兩條語句分別定義了一個MTF的規(guī)則,規(guī)則語句以relate關(guān)鍵字作為開頭,包含一個規(guī)則名稱和參數(shù)列表。目前我們只知道,sample2這條規(guī)則定義了file1和file2之間的約束。參考上面的規(guī)則定義,我們知道:sample2是一條MTF規(guī)則,它定義了一組約束,用來約束file1和file2這兩個對象。如果約束被滿足,則file1和file2就不需要改變。
但是約束是怎么表現(xiàn)的呢?可以看看mapPackages規(guī)則中的一個約束:
equals(pkg1.name, pkg2.name ),
這是一個典型的MTF規(guī)則約束,equals是一個關(guān)鍵字,它的含義是它的兩個參數(shù)必須相同,否則約束就被違背了。這里“equals”的含義等于java語言中的Object.equals()。
至此,我們已經(jīng)明白了規(guī)則、映射和約束的含義。但是映射組具體是什么?它如何產(chǎn)生映射?以及約束如果被違背了怎么辦?目前都不知道。
MTF中的和解(Reconciliation)
MTF的第二個重要的概念就是和解(Reconciliation),也許還能夠翻譯為調(diào)解、調(diào)停等,不過姑且先稱之為和解吧,并不妨礙理解。
MTF對于和解是這樣定義的:Reconciliation is the process of modifying mapped model objects in order to fix constraint violations. Reconciliation is carried out by a transformation engine – which in MTF happens to be the same thing as the mapping engine.
和解是一個通過修改參與映射的模型元素來修復(fù)被破壞的規(guī)則的過程。和解是被轉(zhuǎn)換引擎執(zhí)行的――它在MTF中常常就是映射引擎。
直觀的來講,和解就是決定了這么一件事:如果前面定義的轉(zhuǎn)換規(guī)則的約束被打破了,那么怎么辦?
和解的意思就是,如果約束被打破,那么我就修改模型元素,直到約束再一次被遵守為止。舉例說明,上面的一個約束:
equals(pkg1.name, pkg2.name ),
它規(guī)定了EMF中的包pkg1和pkg2的名稱必須相同,如果file1和file2中相應(yīng)的包名稱不同,那么約束就被破壞了。此時需要和解,和解在執(zhí)行時修改了file2(或者是file1,根據(jù)配置的映射方向來決定)的pkg2的包名稱,那么這個約束就被修復(fù)了。
如果有的約束無法修復(fù)怎么辦?那么就會報錯,轉(zhuǎn)換無法執(zhí)行。
至此基本明白了MTF的轉(zhuǎn)換原理:
l 先定義兩個模型之間的轉(zhuǎn)換規(guī)則,每條規(guī)則包含一些轉(zhuǎn)換約束;
l 然后導(dǎo)入實際的模型,執(zhí)行轉(zhuǎn)換規(guī)則;
l 如果所有規(guī)則的約束都被滿足,則說明源模型和目標模型符合轉(zhuǎn)換規(guī)則;
l 如果有一些規(guī)則的約束被打破了,則啟動和解,和解會修改目標模型(或者源模型,要根據(jù)配置的映射方向來決定)的某些模型元素,來修復(fù)約束;
l 如果所有的約束都被修復(fù)了,則說明轉(zhuǎn)換成功,此時源模型和目標模型符合轉(zhuǎn)換規(guī)則;
l 如果有些約束無法修復(fù),則報錯退出,說明源模型不能正確轉(zhuǎn)換為目標模型。
再來看看我注釋過的sample2:
import ecore "http://www.eclipse.org/emf/2002/Ecore" //導(dǎo)入ECORE模型
import emf "http:///com/ibm/mtf/model/emf.ecore" //導(dǎo)入EMF模型
import ws "http:///com/ibm/mtf/model/workspace.ecore"//導(dǎo)入Eclipse的workspace
//定義規(guī)則sample2,它是轉(zhuǎn)換的入口規(guī)則,參數(shù)file1是源模型所在的文件,file2是目標模型所在的文件
relate sample2(ws:IFile file1, ws:IFile file2)
{
//包含子規(guī)則mapPackages,over關(guān)鍵字的含義是對集合中的元素依次執(zhí)行規(guī)則
//file1.resource.contents的結(jié)果是一個EPackage的集合
mapPackages(over file1.resource.contents, over file2.resource.contents)
}
//定義子規(guī)則mapPackages,參數(shù)是源模型和目標模型的EPackage
relate mapPackages(ecore:EPackage pkg1, ecore:EPackage pkg2 )
{
//約束:pkg1和pkg2的名稱必須相同
equals(pkg1.name, pkg2.name ),
//遞歸執(zhí)行規(guī)則mapPackages,參數(shù)是pkg1和pkg2的子包
//ordered關(guān)鍵字的含義是規(guī)則必須按照順序來執(zhí)行,兩個集合中的元素必須一一對應(yīng)
ordered mapPackages( over pkg1.eSubpackages, over pkg2.eSubpackages)
}
小結(jié)
MTF的設(shè)計比較巧妙,通過規(guī)則――約束――破壞――和解,來達到執(zhí)行模型轉(zhuǎn)換的目的。而且規(guī)則可以雙向執(zhí)行,這是QVT規(guī)范要求的一個特性。不過雙向執(zhí)行的規(guī)則約束要更嚴格,功能也弱一些。
另外,我認為MTF的一些缺點是:
規(guī)則語言需要太多學習時間,目前沒有等效的數(shù)學描述;
約束的表達能力太弱,比起OCL遠遠不如。至少我目前感覺如此,也許是很多實用的util包沒有接觸到吧。OCL作為UML約束語言的規(guī)范,應(yīng)該是比較有前途的,但是MTF沒有使用OCL,而是自己開發(fā)了一套規(guī)則約束的表達方式。
不過,MTF作為一個模型轉(zhuǎn)換工具的代表作,其作用也是巨大的。模型轉(zhuǎn)換的研究也有好幾年了,QVT規(guī)范還沒有出臺。很多研究人員只是停留在理論階段,沒有實踐,也缺少實踐的工具。MTF提供了一個較好的模型轉(zhuǎn)換工具,可以用來驗證各種模型轉(zhuǎn)換的理論。更重要的是,它提供了擴展機制,用戶可以擴展目前的MTF,來實現(xiàn)自己的轉(zhuǎn)換工具。最后,MTF是基于Ecilpse開發(fā)的,搭乘Eclipse的春風,應(yīng)該能夠飛得遠一些吧。
此篇僅僅是一個簡介,待更熟悉MTF后,再寫心得吧。
Blog好久沒有更新,連老婆都罵我懶,唉。。。