1. ATL簡介
ATL是ATLAS轉(zhuǎn)換語言的簡稱,它是ATLAS研究組開發(fā)出來的一種符合OMG的一個(gè)QVT提案的模型轉(zhuǎn)換語言。目前ATL已經(jīng)實(shí)現(xiàn)為ADT的一個(gè)組成部分,ADT是一個(gè)Eclipse插件,他是著名的Eclipse項(xiàng)目GMT的子項(xiàng)目。ATL是基于EMF(Eclipse模型框架)的,其元模型、模型都是用EMF來描述的。
從本質(zhì)上來說,ATL屬于基于規(guī)則的模型轉(zhuǎn)換語言,其中使用了OCL作為約束描述語言。ATL是一種混合語言,既有描述性語言的特征,又含有命令式語言的內(nèi)容。作為一種基于規(guī)則的語言,描述性是其最主要特征,但是為了完成某些復(fù)雜的轉(zhuǎn)換,命令式的內(nèi)容也被加進(jìn)去了。
目前ATL屬于三個(gè)組織,ATLAS研究組、LINA & INRIA(這應(yīng)該是一個(gè)法國的研究機(jī)構(gòu),主頁上是法文,看不懂)和法國Nantes大學(xué)。
2. ATL安裝簡介
在ADT的文檔頁面上面有關(guān)于ATL和ADT的大部分文檔,包括安裝手冊、初學(xué)者手冊和用戶手冊等等。2,3,4節(jié)簡要的說明了其中的內(nèi)容。
安裝步驟如下:
首先安裝Eclipse3.1和EMF2.1.0:
Eclipse is available at http://www.eclipse.org/downloads/index.php. Select the release 3.1(eclipse-SDK-3.1-win32.zip).
EMF can be downloaded from http://download.eclipse.org/tools/emf/scripts/downloads.php.
Select the release 2.1.0 (emf-sdo-runtime-2.1.0.zip).
然后安裝ADT,它在http://www.eclipse.org/gmt/atl/download/,選擇adt-20051102.zip包下載。然后按照Eclipse插件的安裝方法安裝插件。
最后還要安裝兩個(gè)其它的java包:
ANTLR can be downloaded from http://www.antlr.org/download.html. Select the “jar file only”(tool and Java runtime) archive (antlr-2.7.5.jar).將這個(gè)jar包改名為antlr.jar,然后拷貝到\eclipse\plugins\org.atl.eclipse.engine_version\lib。
MDR is available at http://mdr.netbeans.org/download/. Select the “MDR zip” archive (mdrstandalone.zip).將這個(gè)zip包解壓縮后得到jmi.jar, jmiutils.jar, mdrapi.jar, mof.jar, nbmdr.jar and openide-util.jar,將這些jar文件拷貝到\eclipse\plugins\org.atl.engine.repositories.mdr4atl_version\lib。
至此ADT才算安裝完成,過程有點(diǎn)復(fù)雜,所以記下來。
3. ATL的Helloworld
ATL的框架結(jié)構(gòu)
ATL的helloworld可不是那么簡單,首先要弄清楚一個(gè)ATL程序需要包含哪些內(nèi)容。而要弄清這些內(nèi)容,最好還是先看看ATL的整個(gè)框架結(jié)構(gòu)。以下就是ATL的模型轉(zhuǎn)換的層次結(jié)構(gòu):
換語言ATL使用感想/image002.gif)
其中Ma是源模型,而Mb是目標(biāo)模型。Ma符合其元模型MMa,而Mb符合其元模型MMb。同時(shí)MMa和MMb都符合唯一的元元模型MMM。Mt是一個(gè)模型轉(zhuǎn)換實(shí)例,它也是一種模型,它符合模型轉(zhuǎn)換的元模型MMt。MMt也符合唯一的元元模型MMM。
在ATL當(dāng)中,唯一的元元模型就是Ecore,其地位等同于MOF。而MMa和MMb則是Ecore創(chuàng)建出來的元模型。Ma和Mb則是符合這些元模型的模型實(shí)例。MMt已經(jīng)被ATL定義好了,Mt則是使用者自己要定義的模型轉(zhuǎn)換模型,也就是模型轉(zhuǎn)換程序。
所以,一個(gè)完整的ATL模型轉(zhuǎn)換程序,需要四個(gè)內(nèi)容:MMa、MMb、Ma、Mt。而生成的目標(biāo)模型則是Mb。
ATL的helloworld
這個(gè)例子出現(xiàn)在ATL Starter’s Guide中。
首先打開Eclipse創(chuàng)建一個(gè)ATL項(xiàng)目,然后依次創(chuàng)建文件Author.km3,Person.km3, Authors.ecore和Author2Person.atl。它們分別代表元源模型、元目標(biāo)模型、源模型和轉(zhuǎn)換程序。
元模型其實(shí)都可以使用EMF來直接創(chuàng)建,但是ATL提供了一個(gè)類似java的語言km3,使用km3定義的元模型可以生成基于EMF的元模型Author.ecore、Person.ecore。
代碼內(nèi)容如下:
Author.km3:
package Author{
class Author{
attribute name : String;
attribute surname: String;
}
}
package PrimitiveTypes{
datatype String;
}
Person.km3:
package Person{
class Person{
attribute name : String;
attribute surname: String;
}
}
package PrimitiveTypes{
datatype String;
}
這兩個(gè)元模型經(jīng)過轉(zhuǎn)換后都成為基于XMI格式的Ecore模型Author.ecore和Person.ecore。
然后給出一個(gè)源模型,它是符合Author.ecore的:
Authors.ecore:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Author">
<Author name="David" surname="Touzet"/>
<Author name="Freddy" surname="Allilaire"/>
</xmi:XMI>
最后是轉(zhuǎn)換程序代碼:
Author2Person.atl
module Author2Person; -- Module Template
create OUT : Person from IN : Author;
uses strings;
rule Author{
from
a: Author!Author
to
p: Person!Person (
name<-a.name,
surname<-a.surname
)
}
代碼的含義可以參考相關(guān)文獻(xiàn),可以看出來,這種基于規(guī)則的代碼簡單的定義了兩個(gè)模型之間的名稱映射。如果要定義更加復(fù)雜的約束,則需要用到更多ATL的知識,這些約束一般都是使用OCL來定義的。
在Eclipse中運(yùn)行這個(gè)程序需要在run as…中進(jìn)行詳細(xì)的配置。也可以參考相關(guān)文獻(xiàn)。運(yùn)行的結(jié)果是一個(gè)目標(biāo)模型Persons.ecore,其內(nèi)容如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Person">
<Person name="Freddy" surname="Allilaire"/>
<Person name="David" surname="Touzet"/>
</xmi:XMI>
當(dāng)然,ecore模型都是可以用EMF的編輯器來進(jìn)行可視化察看的,并不是都使用XMI格式來察看。而且,在熟悉了之后可以使用EMF來直接創(chuàng)建元模型,我覺得比學(xué)習(xí)和使用KM3語言要稍微快一點(diǎn)。
至此我們完成了ATL的這個(gè)helloworld,看起來有一點(diǎn)復(fù)雜,需要的知識面也比較廣泛。如果對于相關(guān)的知識都有一定程度的了解,可能會(huì)比較輕松上手。
4. 另一個(gè)ATL例子代碼
這個(gè)例子出現(xiàn)在ATL User Manual中,但是只有轉(zhuǎn)換程序代碼,其它的三個(gè)代碼都沒有,因此我補(bǔ)全了其它代碼,使之可以運(yùn)行。
這個(gè)例子的目的如下:MMa描述了一本書的模型,這本書含有許多章節(jié),每個(gè)章節(jié)都有頁數(shù)、名稱和作者。MMb描述了一個(gè)出版物的模型,這個(gè)出版物只包括了一個(gè)總的名稱、作者和頁數(shù)。那么轉(zhuǎn)換程序的目的是將書的所有章節(jié)作者合并到出版物的作者字符串,將書的所有章節(jié)的字?jǐn)?shù)相加得到出版物的字?jǐn)?shù)。
MMa的代碼如下(我使用EMF直接創(chuàng)建了它,但是這里列出的是文本內(nèi)容)Book.ecore
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore">
<ecore:EPackage xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Book">
<eClassifiers xsi:type="ecore:EClass" name="Book">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="chapters" upperBound="-1"
eType="#//Chapter"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Chapter">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="nbPages" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="author" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
</ecore:EPackage>
</xmi:XMI>
MMb的代碼如下Publication.ecore
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore">
<ecore:EPackage xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Publication">
<eClassifiers xsi:type="ecore:EClass" name="Publication">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="nbPages" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="authors" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
</ecore:EPackage>
</xmi:XMI>
Ma的代碼如下Books.ecore
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Book">
<Book title="WxbBook">
<chapters nbPages="12" title="chapter1" author="author1"/>
<chapters nbPages="15" title="chapter2" author="author2"/>
<chapters nbPages="20" title="chapter3" author="author3"/>
</Book>
</xmi:XMI>
Mt的代碼如下Book2Publication.atl,這個(gè)代碼是手冊中提供的,我還是列在這里:
module Book2Publication; -- Module Template
create OUT : Publication from IN : Book;
helper context Book!Book def : getAuthors() : String =
self.chapters->collect(e | e.author)->asSet()
->iterate(authorName; acc : String = '' |
acc +
if acc = ''
then authorName
else ' and ' + authorName
endif
);
helper context Book!Book def : getNbPages() : Integer =
self.chapters->collect(f|f.nbPages)
->iterate(pages; acc : Integer = 0 |
acc + pages
);
rule Book2Publication {
from
b : Book!Book (
b.getNbPages() > 2
)
to
out : Publication!Publication (
title <- b.title,
authors <- b.getAuthors(),
nbPages <- b.getNbPages()
)
}
從Mt的代碼可以看出,為了實(shí)現(xiàn)轉(zhuǎn)換中的約束,定義了兩個(gè)helper函數(shù),函數(shù)都是使用OCL來定義的。并且在轉(zhuǎn)換規(guī)則中調(diào)用了這些函數(shù)。在規(guī)則開頭的限定條件中也調(diào)用了這些函數(shù)。
那么進(jìn)行轉(zhuǎn)換后得到的代碼如下,Publications.ecore
<?xml version="1.0" encoding="ISO-8859-1"?>
<Publication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Publication" title="WxbBook" nbPages="47" authors="author3 and author1 and author2"/>
本節(jié)的內(nèi)容主要是想把用戶手冊中沒有提供的代碼補(bǔ)全,讓初學(xué)者可以直接運(yùn)行這個(gè)例子,可以了解ATL的一部分功能。
5. ATL使用感想
通過這一天的對ATL的了解和使用,有一點(diǎn)點(diǎn)心得。
ATL和MTF的比較
在目前能夠run的模型轉(zhuǎn)換語言中,MTF和ATL都是比較著名的。MTF是IBM開發(fā)的模型轉(zhuǎn)換框架,而ATL則是Eclipse的GMT中包含的模型轉(zhuǎn)換語言。從影響力來看,旗鼓相當(dāng)。使用者的人數(shù)不好統(tǒng)計(jì),況且目前好像都還沒有商業(yè)化,也看不出市場占有率。不過從純技術(shù)的角度來比較這兩個(gè)語言,也是很有意義的。
從上手的難易度來看,無疑MTF是比ATL容易得多。MTF作為一個(gè)準(zhǔn)商業(yè)化的軟件,遵循了簡單易用的原則。而ATL作為一個(gè)研究者團(tuán)體開發(fā)的開源軟件,上手則比較困難。從安裝上來看,MTF是一個(gè)標(biāo)準(zhǔn)的Eclipse插件,基于EMF插件,安裝一步到位。而ATL則需要另外安裝兩個(gè)其它的jar包。從提供的例子程序來看,MTF提供了完整的例子程序包,由易到難循序漸進(jìn),在運(yùn)行helloworld的時(shí)候僅僅需要一個(gè)規(guī)則文件即可憑空構(gòu)造一個(gè)目標(biāo)模型,再以這個(gè)目標(biāo)模型作為源模型構(gòu)造更多的目標(biāo)模型。而ATL在運(yùn)行第一個(gè)Helloworld例子時(shí)則需要手工輸入源元模型、目標(biāo)元模型、源模型和規(guī)則文件。導(dǎo)致復(fù)雜性大幅度增加。而且,除了轉(zhuǎn)換語言ATL以外,還引入了元模型描述語言KM3,而不是直接使用EMF。這樣也增加了上手的困難程度。
從技術(shù)路線來看,MTF和ATL都是基于Eclipse平臺和EMF。而且,它們都是基于規(guī)則的轉(zhuǎn)換語言。不同之處在于,MTF更加傾向于構(gòu)造一個(gè)完全描述性的語言,而ATL則傾向于構(gòu)造一個(gè)描述性和命令行共存的混合語言。這就導(dǎo)致了MTF可以更多的用來描述雙向轉(zhuǎn)換規(guī)則,即源模型和目標(biāo)模型可以對等轉(zhuǎn)換。而ATL則一般用來描述單向轉(zhuǎn)換規(guī)則。但是有得必有失,我認(rèn)為MTF描述復(fù)雜規(guī)則的能力要比ATL弱。因?yàn)?/SPAN>ATL使用了OCL作為約束描述語言,它基本上實(shí)現(xiàn)了OCL(有些地方略為有更改),從上文就可以看出,使用OCL定義的ATL函數(shù)功能是比較強(qiáng)大的。而MTF則沒有使用OCL來定義約束,而是使用一種中庸的簡單比較功能來限定轉(zhuǎn)換的條件。這樣在寫轉(zhuǎn)換規(guī)則的時(shí)候就有一種便秘的感覺,明明我非常了解這個(gè)約束,但是不能夠痛快的寫出來。而且,如果在源模型中使用OCL定義了某種約束,那么在MTF的轉(zhuǎn)換中必然不能直接的使用或者體現(xiàn)這個(gè)約束。相比之下,ATL的功能更加強(qiáng)大一些。
另外有一點(diǎn)值得注意的是,MTF和ATL的作者對于模型層次的理解顯然有點(diǎn)差別。在MTF中,模型層次和MOF中的四層模型是一致的。MTF在M2層定義轉(zhuǎn)換規(guī)則,進(jìn)行轉(zhuǎn)換的是M1層的模型。例如,定義了簡化的UML和簡化的RDBMS之間的轉(zhuǎn)換規(guī)則,可以將UML中的類轉(zhuǎn)換為關(guān)系數(shù)據(jù)庫中的表。但是ATL的模型層次則大部分時(shí)候是在M1層定義轉(zhuǎn)換,而進(jìn)行轉(zhuǎn)換的是M0層的模型,即對象模型。例如第4節(jié)的例子。當(dāng)然,所謂的“元”只是一個(gè)相互對應(yīng)的概念,更抽象的便可稱之為“元”。MTF和ATL都可以用處轉(zhuǎn)換各個(gè)模型層次的模型,只是從它們提供的例子可以看出它們作者的偏好。從這個(gè)角度來看,MTF更加符合大眾的口味。
總而言之,MTF是易于上手的,容易理解的,雙向的描述性模型轉(zhuǎn)換語言,其描述規(guī)則的能力一般,往往要繞圈子來定義規(guī)則。而ATL是開源的,難于上手和掌握的,單向的混合型(描述性和命令行并存)模型轉(zhuǎn)換語言,使用OCL來描述約束,描述規(guī)則的能力較好,使用范圍較廣。
ATL的前景
MDA是一個(gè)較新的概念,也是一個(gè)爭議很大的技術(shù)。但是模型轉(zhuǎn)換作為MDA的核心技術(shù)卻是毫無疑問的。廣義的模型轉(zhuǎn)換技術(shù)其實(shí)和XSLT一樣,將一種格式化的模型(文檔)轉(zhuǎn)換為另一種格式化的模型(文檔)。所以它是有著廣泛的用途和強(qiáng)大的生命力的。
ATL作為模型轉(zhuǎn)換語言中的一個(gè)出色的實(shí)現(xiàn),依托于Eclipse這個(gè)平臺,應(yīng)該是有著比較光明的背景的。遺憾的是,學(xué)習(xí)和使用ATL所需的背景知識比較多,使用起來也不是很容易上手。我可以看見ATLAS已經(jīng)在努力克服這些問題,最近他們實(shí)現(xiàn)了模型編織的工具,用來生成ATL的模型轉(zhuǎn)換代碼。從模型編織的理論上來看,是比較優(yōu)秀和完美的,但是ModelWeaver我還沒有體驗(yàn)過,因此并不知道是否可以克服ATL目前的缺點(diǎn)。
6. 小結(jié)
我很遺憾的發(fā)現(xiàn)關(guān)于ATL網(wǎng)上似乎沒有任何的中文文獻(xiàn),包括MDA技術(shù)也大多是泛泛而談,涉及到具體的工具、理論的很少。愿這篇文章,可以給那些有志于了解模型轉(zhuǎn)換技術(shù)的人一個(gè)引路石。