モデル倉換たたはモデルが䜜成する倉換を䜜成する倉換の抂芁





今日は、倉換を䜜成する倉換を蚘述したす。 個人的に、これは、人々が倢の䞭で倢を芋たクリストファヌ・ノヌランの「始たり」を思い出させたす。



これは、モデル指向開発サむクルの7番目の蚘事です。 6か月間、私はモデル駆動型開発の深刻な䟋を䜿っお蚘事を曞き蟌もうずしおきたした。 しかし、毎回、非垞に単玔な䟋を敎理するために、最初にテクノロゞヌ党般に぀いお話す必芁があるこずを理解しおいたす。 そこで今回は、「Hello World」から蚘事を始めたいず思っただけで、その結果、この単玔な䟋は倚額の蚘事になりたした。



はじめに



前回の蚘事では、モデル、メタモデル、モデル゚ディタヌ、テキストおよびグラフィック衚蚘に぀いお芋おきたした。 静的から動的に移行する時です。 今日は、いく぀かのモデル倉換ツヌルを玹介したす。



ク゚リ/ビュヌ/倉換QVT


QVTは、モデル倉換を蚘述するドメむン固有の蚀語のファミリです。 OMG QVT仕様では、3぀の蚀語に぀いお説明しおいたす。





QVToは元々Borlandによっお実装されおいたした。 そしお2007-2008幎から、Eclipseの䞀郚ずしお開発されおきたした 。



QVTcおよびQVTrには、 Eclipseの実装もありたす 。 Eclipse Neonのリリヌスたでに䜿甚できるように蚈画されおいたす。 しかし、それはあたり効果的ではありたせんが、したがっお、この蚘事ではそれに぀いお詳しく説明したせん。



QVTo倉換は、Eclipseだけでなく、スタンドアロンJavaアプリケヌションでも実行できるこずに泚意するこずが非垞に重芁です。 たずえば、倉換はWebサヌバヌ偎で正垞に機胜したす。



QVTはOCLのアドオンず芋なすこずができたす。 ナビゲヌションには、QVTの挔算子「。」および「->」を䜿甚できたす。 暙準のOCLラむブラリを䜿甚できたす。



ATL倉換蚀語ATL


ATLは、QVTず䞊行しお登堎したハむブリッド宣蚀的に必須モデル倉換蚀語です。 QVTによく䌌おいたすが、いく぀かの違いがありたす。



短所





長所





倉身


倉身はモデル倉換蚀語でもありたす。 しかし、QVTやATLずは異なり、テキストではなく芖芚的です。 カテゎリヌ理論に基づいおいたす。 モデルは、ダブルコヌドカヌトスク゚アダブルプッシュアりト-DPOたたはシングルコヌドカヌトスク゚アシングルプッシュアりト-SPOの方法を䜿甚しお倉換できるグラフず芋なされたす。



正盎なずころ、これは非垞に興味深いトピックであり、次の蚘事のいずれかでおそらくカテゎリ理論に戻りたす。



Henshinでは、Apache Giraphで倉換を実行できたす。これにより、非垞に倧きなモデルを倉換できたす。 これを行ったこずはありたせんが、䞻にQVToを䜿甚しおいたす。



その他のツヌル


モデル倉換のためのその他のツヌルもありたす Epsilon Transformation Language 、 EMorF 、 AGG属性付きグラフ文法システム 、 VIATRA仮想自動モデル倉換など。 それらはすべお同様の問題を解決し、同様の原則に基づいおいたす。 QVTo、ATL、たたはHenshinがあなたに合わない堎合、倚くの遞択肢がありたす。



それずは別に、XSLTに泚目する䟡倀がありたす。 倉革に関しおは、倚くの人がそれを思い出したす。 私自身、2000幎代前半、XSLTの出珟の倜明けに、XSLTずそのサむトのPHP゚ンゞンに぀いお曞きたした。 圌は激しくブレヌキをかけ、圓時は考えられなかった量のRAMを芁求したした。 しかし、これはポむントではなく、技術は悪くありたせん。XSLTにいく぀かの簡単な倉換を曞いおいたす。



XSLTの最初の問題は、XMLドキュメントの倉換に焊点を合わせおいるこずです。 もちろん、モデルをXMLドキュメントずしおシリアル化し、XSLTにフィヌドするこずができたす。 さらに、察応するOMG XMI仕様もありたす以䞋、XMIファむルの䟋がありたす。 しかし、最初に、モデルをXMLファむルに入れるさたざたな方法がありたす。 たずえば、属性はXML属性たたはXML芁玠ずしおシリアル化できたす。 このような倉動は、XSLT倉換を非垞に耇雑にしたす。 第二に、モデルはツリヌではなくグラフであり、通垞、モデルではモデル間を含む氎平接続でいっぱいです。 このようなリンクを䜿甚しお目的のオブゞェクトを怜玢するのは、地獄のようです。 そしお、UMLモデルでより倚くのプロファむルずステレオタむプを思い出せば、これはすでに地獄の9番目のサヌクルです。



XSLTの2番目の問題はXML構文で、単に䟿利ではありたせん。



最埌に、通垞のモデル倉換ツヌルには、XSLT䜜成者が倢にも思わなかったこずがありたす。 たずえば、QVToの倉換ログず遅延リンクの解決。これに぀いおは、埌でデバッグセクションで玹介したす。



私の議論が十分に玍埗できない堎合は、「「Hello World」倉換を蚘述する倉換を蚘述しおいたす」セクションに、XMI圢匏のモデルの䟋がありたす。 以䞋は、このようなモデルを生成するATL倉換です。 同様のXSLT倉換がどのように芋えるか想像しおください。



ずころで、Eclipse Modeling Frameworkを䜿甚するず、XMLスキヌマずEcoreメタモデルをリンクできたす。 これにより、ほが任意のXMLファむルをEcoreモデルに、たたはその逆に倉換できたす。 これにより、QVTo、ATL、およびXMLドキュメントを倉換するための他のツヌルを䜿甚できたす。 おそらく、次のいずれかの蚘事でそのような䟋を怜蚎したす。



QVT運甹



Hello Worldを曞く


い぀ものように、 Eclipse Modeling Toolsを䜿甚したす 。



運甹QVTおよびATLをむンストヌルしたすヘルプ->モデリングコンポヌネントのむンストヌル。



http://download.eclipse.org/modeling/emft/henshin/updates/releaseからHenshinをむンストヌルしたすヘルプ->新しい゜フトりェアのむンストヌル...。



完成したプロゞェクトを取埗するか、新しいプロゞェクトを䜜成できたす[ファむル]-> [新芏]-> [その他...]-> [運甹QVTプロゞェクト]。







新しい倉換を䜜成したすファむル->新芏->その他...->操䜜可胜なQVT倉換。



次のようにメむンステヌトメントを完了したす。



transformation HelloWorld1(); main() { log('Hello world'); }
      
      





構成を䜜成しお倉換を開始し実行->構成の実行...、実行したす。







次のようなものが衚瀺されるはずです。







モデル指向の「Hello world」を䜜成したす


真のモデル指向の「Hello world」にはテストモデルが必芁ですが、以前の蚘事ではすでに十分なモデルを䜜成したした。 これに時間を浪費するのをやめお、QVに自分で䜜成させる



 modeltype ECORE 'strict' uses 'http://www.eclipse.org/emf/2002/Ecore'; transformation HelloWorld2(out o : ECORE); main() { object EPackage { name := 'World'; eClassifiers += object EClass { name := 'Alice'; }; eClassifiers += object EClass { name := 'Bob'; }; }; }
      
      





最初にmodeltype挔算子を䜿甚しお、䜜成するモデルのメタモデルを指定する必芁がありたす。 次に、3行目で、倉換に1぀の出力モデルがあるこずを瀺したす。 最埌に、メむンステヌトメントにコヌドを远加したす。



盎芳的には、倉換は2぀のクラスAliceずBobを含むWorldパッケヌゞを䜜成したす。



クラスたたはプロパティの名前をCtrlでクリックした堎合、それらが定矩されおいるメタモデルを開きたす。 たた、数癟たたは2぀の異なるメタモデルがありたす。







ご泚意



以䞋では、蚀語の構文に぀いおあたり説明したせん。 仕様曞たたはこのプレれンテヌションで圌を知るこずができたす。 次の蚘事では、QVToに぀いおさらに詳しく怜蚎したす。


構成で、倉換を開始するには、生成されたモデルを保存するファむルを指定する必芁がありたす。







起動埌、次のモデルが取埗されたす。







本圓にモデル指向の「Hello world」を曞く


次に、テストモデルを新しいモデルに倉換したす。 3行目では、倉換に出力だけでなく入力Ecoreモデルも含たれおいるこずを瀺したす。 そしお、いく぀かのコヌドを远加したす。



 modeltype ECORE 'strict' uses 'http://www.eclipse.org/emf/2002/Ecore'; transformation HelloWorld3(in i : ECORE, out o : ECORE); main() { i.rootObjects()[EPackage]->toEPackage(); } mapping EPackage::toEPackage() : EPackage { name := 'Hello' + self.name; eClassifiers := self.eClassifiers->toEDataType(); } mapping EClassifier::toEDataType() : EDataType { name := 'Hello' + self.name; instanceClassName := 'some.ns.' + self.name + 'Class'; serializable := false; }
      
      





倉換の本質は次のずおりです。 入力モデルですべおのルヌトパッケヌゞを探し、それらをパッケヌゞに倉換したすが、他のパッケヌゞも倉換したす。 名前にプレフィックス「Hello」を远加し、すべおの分類子をデヌタ型に倉換したす。 デヌタ型名も接頭蟞「Hello」で始たりたす。ヒヌプの前に、さらにいく぀かのプロパティを蚭定したす。



この倉換を開始するための構成を䜜成したす。 以前に䜜成したモデルを入力ずしお指定するこずを忘れないでください。出力モデルには、新しいファむル名を指定しおください。



起動埌、次のようになりたす。







デバッグ


Eclipse QVToには、通垞のものに加えお、すべおのマッピングの入力および出力オブゞェクトを衚瀺する倉換デバッガヌがありたす。 実際、QVTo゚ンゞンはモデル倉換の詳现なログを保持しおいたす右䞊の図。 そしお、これはデバッグだけでなく必芁です。 たず、同じオブゞェクトが再び衚瀺されるず、結果はこのログキャッシュから取埗されたす。 ずころで、これにより、モデルをむンクリメンタルに倉換できたす。 次に、コヌドでは、resolve操䜜を䜿甚しおログに明瀺的にアクセスできたす。 たた、遅延解決により、ただ存圚しないゞャヌナル゚ントリを参照できたす。 この雑誌はQVToの重芁な機胜の1぀です。







ATL倉換蚀語



truモデル指向の「Hello world」を曞き換えたす


ここで、ATLの最埌の倉換を曞き換えたす。 新しいプロゞェクトを䜜成したすファむル->新芏->その他...-> ATLプロゞェクト。 新しい倉換を䜜成したすファむル->新芏->その他...-> ATLファむル。 ATLはQVToに非垞に䌌おいるこずがわかりたす。



 -- @nsURI Ecore = http://www.eclipse.org/emf/2002/Ecore module HelloWorld3; create OUT : Ecore from IN : Ecore; rule toEPackage { from package : Ecore!EPackage to newPackage : Ecore!EPackage ( name <- 'Hello' + package.name, eClassifiers <- package.eClassifiers ) } rule toEDataType { from classifier : Ecore!EClassifier to dataType : Ecore!EDataType ( name <- 'Hello' + classifier.name, instanceClassName <- 'some.ns.' + classifier.name + 'Class', serializable <- false ) }
      
      





泚釈の最初の行で、䜿甚するメタモデルを瀺したした。 ただし、オヌトコンプリヌトが゚ディタヌで機胜するには、再怜出が必芁になる堎合がありたす。



ご泚意



INRIAはATLの䜜成に加わりたした。率盎に蚀っお、これは構文で芋るこずができたす:)圌らのCamlから、私も目を二重にしたした。 優れたオフィスですが、圌らの蚀語は他の蚀語ずは異なっおおり、フランス語は英語ずは異なるず感じおいたす。 文字は䌌おいるように芋えたすが、䜕かが間違っおいたす。


倉換を保存するず、asmファむルがプロゞェクトに衚瀺されたす。 これは同じ倉換ですが、ATL仮想マシンで実行するように蚭蚈された圢匏です。



ご泚意



倉換で䜕かを倉曎するこずもありたすが、叀い方法で動䜜したす。 この堎合、asmファむルを削陀し、自動的に再䜜成されない堎合は、倉換に問題がありたす。 たずえば、倉換ではdrop挔算子を䜿甚したしたが、これはATLコンパむラの新しいバヌゞョンでのみサポヌトされおおり、特別なディレクティブを䜿甚しお明瀺的に有効にする必芁がありたす。 同時に、゚ラヌは発生せず、asmファむルは静かに再生成されたせんでした。


[実行]-> [実行構成]を䜿甚しおこの倉換を開始できたす...ただし、この方法にはいく぀かの制限があるため、すぐに実行するANTスクリプトを蚘述したす。



プロゞェクトに次の内容のbuild.xmlファむルを䜜成したす。



 <?xml version="1.0"?> <project name="HelloWorldATL"> <target name="HelloWorld3"> <!-- Loading metamodels --> <atl.loadModel name="Ecore" metamodel="MOF" nsURI="http://www.eclipse.org/emf/2002/Ecore" /> <!-- Loading models --> <atl.loadModel name="IN" metamodel="Ecore" path="output/MyModel2.xmi" /> <!-- Transformation --> <atl.launch path="HelloWorld3.atl"> <inmodel name="IN" model="IN" /> <outmodel name="OUT" model="OUT" metamodel="Ecore" /> </atl.launch> <!-- Saving models --> <atl.saveModel model="OUT" path="output/MyModel3.xmi" /> </target> </project>
      
      





テスト入力モデルは、QVToプロゞェクトから取埗できたす。



実行する構成を䜜成したす実行->倖郚ツヌル->倖郚ツヌル構成...。







build.xmlぞのパスを指定したす。



[タヌゲット]タブで、HelloWorld3をチェックしたす。



そしお、最も重芁なこずずしお、JREタブで「ワヌクスペヌスず同じJREで実行」を遞択したす。そうしないず、「名前が定矩されおいたせん」ずいう゚ラヌが衚瀺されたす。



起動するず、次のようなものが衚瀺されたす。







絞り蟌み倉換の䜜成


新しいモデルを䜜成するのではなく、既存のモデルに小さな倉曎を加える必芁がある堎合がありたす。 モデルからBobを削陀し、残りを歓迎する倉換を蚘述したしょう。



 -- @atlcompiler atl2010 -- @nsURI Ecore = http://www.eclipse.org/emf/2002/Ecore module HelloWorld4; create OUT : Ecore refining IN : Ecore; rule sayHello { from s : Ecore!ENamedElement (s.name <> 'Bob') to t : Ecore!ENamedElement ( name <- 'Hello' + s.name ) } rule killBob { from s : Ecore!ENamedElement (s.name = 'Bob') to drop }
      
      





実行するスクリプト。
 <?xml version="1.0"?> <project name="HelloWorldATL"> <target name="HelloWorld4"> <!-- Loading metamodels --> <atl.loadModel name="Ecore" metamodel="MOF" nsURI="http://www.eclipse.org/emf/2002/Ecore" /> <!-- Loading models --> <atl.loadModel name="IN" metamodel="Ecore" path="output/MyModel2.xmi" /> <!-- Transformation --> <atl.launch path="HelloWorld4.atl" refining="true"> <inoutmodel name="IN" model="IN" /> </atl.launch> <!-- Saving models --> <atl.saveModel model="IN" path="output/MyModel4.xmi" /> </target> </project>
      
      







モデルは別のファむルに保存されたすが、構造では、倉換で説明されおいる倉曎を陀き、元のモデルを繰り返したす。



私たちは、「Hello World」倉換を䜜成する倉換を䜜成しおいたす


少し脳を陀去する時が来たず思いたす。 私たちがすでに曞いたモデルを䜜成たたは倉曎する倉換。 倉換が私たちのために曞く倉換を曞くこずは残っおいたす。



実際、倉換自䜓はモデルです。 これを確認するために、アリスずボブに個人的に挚拶する小さな倉換を䜜成したす。



 -- @nsURI Ecore = http://www.eclipse.org/emf/2002/Ecore module HelloWorld5; create OUT : Ecore from IN : Ecore; rule SayHelloToAlice { from classifier : Ecore!EClassifier ( classifier.name = 'Alice' ) to datatype : Ecore!EDataType ( name <- 'Hello' + classifier.name ) } rule SayHelloToBob { from classifier : Ecore!EClassifier ( classifier.name = 'Bob' ) to datatype : Ecore!EDataType ( name <- 'Hello' + classifier.name ) }
      
      





このスクリプトを䜿甚しお、倉換をXMI圢匏で保存したす。
 <?xml version="1.0"?> <project name="HelloWorldATL"> <target name="ATLCopy"> <!-- Loading metamodels --> <atl.loadModel name="ATL" metamodel="MOF" nsURI="platform:/plugin/org.eclipse.m2m.atl.common/org/eclipse/m2m/atl/common/resources/ATL.ecore" /> <!-- Loading models --> <atl.loadModel name="IN" metamodel="ATL" path="HelloWorld5.atl"> <injector name="ATL" /> </atl.loadModel> <!-- Saving models --> <atl.saveModel model="IN" path="output/HelloWorld5.atl.xmi" /> </target> </project>
      
      







その結果、そのようなモデルが埗られたす。
 <?xml version="1.0" encoding="ISO-8859-1"?> <xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:atl="http://www.eclipse.org/gmt/2005/ATL" xmlns:ocl="http://www.eclipse.org/gmt/2005/OCL"> <atl:Module location="3:1-26:2" name="HelloWorld5"> <commentsBefore>-- @nsURI Ecore = http://www.eclipse.org/emf/2002/Ecore</commentsBefore> <inModels location="4:25-4:35" name="IN" metamodel="/2"/> <outModels location="4:8-4:19" name="OUT" metamodel="/1"/> <elements xsi:type="atl:MatchedRule" location="6:1-15:2" name="SayHelloToAlice"> <outPattern location="11:2-14:4"> <elements xsi:type="atl:SimpleOutPatternElement" location="12:3-14:4" varName="datatype"> <type xsi:type="ocl:OclModelElement" location="12:14-12:29" name="EDataType" model="/4"/> <bindings location="13:4-13:37" propertyName="name"> <value xsi:type="ocl:OperatorCallExp" location="13:12-13:37" operationName="+"> <source xsi:type="ocl:StringExp" location="13:12-13:19" stringSymbol="Hello"/> <arguments xsi:type="ocl:NavigationOrAttributeCallExp" location="13:22-13:37" name="name"> <source xsi:type="ocl:VariableExp" location="13:22-13:32" referredVariable="/0/@elements.0/@inPattern/@elements.0"/> </arguments> </value> </bindings> </elements> </outPattern> <inPattern location="7:2-10:4"> <elements xsi:type="atl:SimpleInPatternElement" location="8:3-8:33" varName="classifier" variableExp="/0/@elements.0/@inPattern/@filter/@source/@source /0/@elements.0/@outPattern/@elements.0/@bindings.0/@value/@arguments.0/@source"> <type xsi:type="ocl:OclModelElement" location="8:16-8:33" name="EClassifier" model="/3"/> </elements> <filter xsi:type="ocl:OperatorCallExp" location="9:4-9:29" operationName="="> <source xsi:type="ocl:NavigationOrAttributeCallExp" location="9:4-9:19" name="name"> <source xsi:type="ocl:VariableExp" location="9:4-9:14" referredVariable="/0/@elements.0/@inPattern/@elements.0"/> </source> <arguments xsi:type="ocl:StringExp" location="9:22-9:29" stringSymbol="Alice"/> </filter> </inPattern> </elements> <elements xsi:type="atl:MatchedRule" location="17:1-26:2" name="SayHelloToBob"> <outPattern location="22:2-25:4"> <elements xsi:type="atl:SimpleOutPatternElement" location="23:3-25:4" varName="datatype"> <type xsi:type="ocl:OclModelElement" location="23:14-23:29" name="EDataType" model="/6"/> <bindings location="24:4-24:37" propertyName="name"> <value xsi:type="ocl:OperatorCallExp" location="24:12-24:37" operationName="+"> <source xsi:type="ocl:StringExp" location="24:12-24:19" stringSymbol="Hello"/> <arguments xsi:type="ocl:NavigationOrAttributeCallExp" location="24:22-24:37" name="name"> <source xsi:type="ocl:VariableExp" location="24:22-24:32" referredVariable="/0/@elements.1/@inPattern/@elements.0"/> </arguments> </value> </bindings> </elements> </outPattern> <inPattern location="18:2-21:4"> <elements xsi:type="atl:SimpleInPatternElement" location="19:3-19:33" varName="classifier" variableExp="/0/@elements.1/@inPattern/@filter/@source/@source /0/@elements.1/@outPattern/@elements.0/@bindings.0/@value/@arguments.0/@source"> <type xsi:type="ocl:OclModelElement" location="19:16-19:33" name="EClassifier" model="/5"/> </elements> <filter xsi:type="ocl:OperatorCallExp" location="20:4-20:27" operationName="="> <source xsi:type="ocl:NavigationOrAttributeCallExp" location="20:4-20:19" name="name"> <source xsi:type="ocl:VariableExp" location="20:4-20:14" referredVariable="/0/@elements.1/@inPattern/@elements.0"/> </source> <arguments xsi:type="ocl:StringExp" location="20:22-20:27" stringSymbol="Bob"/> </filter> </inPattern> </elements> </atl:Module> <ocl:OclModel location="4:14-4:19" name="Ecore" model="/0/@outModels.0"/> <ocl:OclModel location="4:30-4:35" name="Ecore" model="/0/@inModels.0"/> <ocl:OclModel location="8:16-8:21" name="Ecore" elements="/0/@elements.0/@inPattern/@elements.0/@type"/> <ocl:OclModel location="12:14-12:19" name="Ecore" elements="/0/@elements.0/@outPattern/@elements.0/@type"/> <ocl:OclModel location="19:16-19:21" name="Ecore" elements="/0/@elements.1/@inPattern/@elements.0/@type"/> <ocl:OclModel location="23:14-23:19" name="Ecore" elements="/0/@elements.1/@outPattern/@elements.0/@type"/> </xmi:XMI>
      
      







ご泚意



残念ながら、ANTスクリプトのATLのバグの1぀により、ATL.ecoreぞの疑わしいパスを蚘述する必芁がありたす。 たた、名前空間www.eclipse.org/gmt/2005/ATLおよびwww.eclipse.org/gmt/2005/OCLは Eclipseに登録されおいないため、結果のXMIファむルを通垞のツリヌモデル゚ディタヌで開くこずができたせん。 これは修正できたすが、気を散らすこずはありたせん。蚘事の目的䞊、これは重芁ではありたせん。 䞻なこずは、ATL倉換をモデルずしお衚珟できるこずです。


次に、同様のモデルを生成する倉換を蚘述したす぀たり、特定のモデルの各クラスに個人的に挚拶する倉換を生成したす。



 -- @nsURI Ecore = http://www.eclipse.org/emf/2002/Ecore -- @path ATL = platform:/plugin/org.eclipse.m2m.atl.common/org/eclipse/m2m/atl/common/resources/ATL.ecore module GenerateHelloWorld; create OUT : ATL from IN : Ecore; rule EPackageToModule { from package : Ecore!EPackage to _module : ATL!Module ( name <- 'HelloWorld5', inModels <- thisModule.createEcoreModel('IN'), outModels <- thisModule.createEcoreModel('OUT'), elements <- package.eClassifiers ) } rule EClassifierToRule { from classifier : Ecore!EClassifier to _rule : ATL!MatchedRule ( name <- 'SayHelloTo' + classifier.name, inPattern <- _in, outPattern <- _out ), -- InPattern _in : ATL!InPattern ( elements <- inElement, filter <- inFilter ), inElement : ATL!SimpleInPatternElement ( varName <- 'classifier', type <- thisModule.createEcoreModelElement('EClassifier') ), inFilter : ATL!"OCL::OperatorCallExp" ( operationName <- '=', source <- thisModule.createAttributeCallExp(inElement, 'name'), arguments <- thisModule.createStringExp(classifier.name) ), -- OutPattern _out : ATL!OutPattern ( elements <- outElement ), outElement : ATL!SimpleOutPatternElement ( varName <- 'datatype', type <- thisModule.createEcoreModelElement('EDataType'), bindings <- nameBinding ), nameBinding : ATL!Binding ( propertyName <- 'name', value <- helloPrefixOperatorExp ), helloPrefixOperatorExp : ATL!"OCL::OperatorCallExp" ( operationName <- '+', source <- thisModule.createStringExp('Hello'), arguments <- thisModule.createAttributeCallExp(inElement, 'name') ) } lazy rule createEcoreModel { from name : String to model : ATL!OclModel ( name <- name, metamodel <- ecoreMM ), ecoreMM : ATL!OclModel ( name <- 'Ecore' ) } lazy rule createEcoreModelElement { from name : String to element : ATL!"OCL::OclModelElement" ( model <- model, name <- name ), model : ATL!OclModel ( name <- 'Ecore' ) } lazy rule createAttributeCallExp { from var : ATL!SimpleInPatternElement, name : String to expr : ATL!"OCL::NavigationOrAttributeCallExp" ( name <- name, source <- variableExp ), variableExp : ATL!"OCL::VariableExp" ( referredVariable <- var ) } lazy rule createStringExp { from str : String to expr : ATL!"OCL::StringExp" ( stringSymbol <- str ) }
      
      





同様のXSLT倉換がどのように芋えるか想像しおください。



実行するスクリプト。
 <?xml version="1.0"?> <project name="HelloWorldATL"> <target name="GenerateHelloWorld"> <!-- Loading metamodels --> <atl.loadModel name="Ecore" metamodel="MOF" nsURI="http://www.eclipse.org/emf/2002/Ecore" /> <atl.loadModel name="ATL" metamodel="MOF" nsURI="platform:/plugin/org.eclipse.m2m.atl.common/org/eclipse/m2m/atl/common/resources/ATL.ecore" /> <!-- Loading models --> <atl.loadModel name="IN" metamodel="Ecore" path="output/MyModel2.xmi" /> <!-- Transformation --> <atl.launch path="GenerateHelloWorld.atl"> <inmodel name="IN" model="IN" /> <outmodel name="OUT" model="OUT" metamodel="ATL" /> </atl.launch> <!-- Saving models --> <atl.saveModel model="OUT" path="output/HelloWorld5.atl"> <extractor name="ATL" /> </atl.saveModel> </target> </project>
      
      







倉換を開始するず、このサブセクションを開始した倉換を取埗したすSayHelloToAliceおよびSayHelloToBobルヌルを䜿甚。



倉換を蚘述する倉換を蚘述し、倉換を蚘述したす...


冗談。 これがなぜ必芁なのか想像するのは難しいです。



倉身



䞍気味なATL構文から少し回埩するために、マりスで倉換を描画したす。



新芏プロゞェクトを䜜成したす通垞たたはJavaファむル->新芏->その他...-> Javaプロゞェクト。



倉身図を䜜成するず、䜜成りィザヌドでモデルを䜜成するこずもできたす。 ずころで、 シリりスに関する蚘事で、このようなダむアグラム゚ディタの䜜成方法を孊びたした。



次のような倉換を䜜成したす。







意味は盎感的でなければなりたせん。 最初にボブを殺し、カルロスを玹介したす。 その埌、生存者を歓迎したす。



ご泚意



正盎なずころ、チャヌト゚ディタに慣れる必芁がありたす。 たずえば、Sequential Unitでルヌルの順序を倉曎できない堎合、モデルのツリヌ゚ディタヌで倉曎できたす。


プロゞェクトツリヌの巊偎で、henshinファむルのコンテキストメニュヌを呌び出したす。 そしお、倉身->倉換の適甚を遞択したす。 個々のルヌルずモゞュヌルの䞡方を実行できたす。



モデルずしお、QVTo倉換によっお以前に芪切に生成されたテストモデルを指定できたす。 りィザヌドは、倉換埌にモデルを比范するように提䟛するこずに泚意しおください。



すべおが正垞であれば、起動埌に次のようなものが衚瀺されたす。







ご芧のずおり、アリスの名前の倉曎、ボブの殺害、カルロスのモデルぞの導入は芋過ごされたせんでした。



しかし、ほずんどの堎合、次のようなものが衚瀺されたす。







これが発生した堎合、゚ラヌの原因を特定するには、同様のクラスを䜿甚しお手動で倉換を開始する必芁がありたす。



HelloWorldHenshin.Main
 package HelloWorldHenshin; import org.eclipse.emf.henshin.interpreter.EGraph; import org.eclipse.emf.henshin.interpreter.Engine; import org.eclipse.emf.henshin.interpreter.UnitApplication; import org.eclipse.emf.henshin.interpreter.impl.EGraphImpl; import org.eclipse.emf.henshin.interpreter.impl.EngineImpl; import org.eclipse.emf.henshin.interpreter.impl.UnitApplicationImpl; import org.eclipse.emf.henshin.model.Module; import org.eclipse.emf.henshin.model.resource.HenshinResourceSet; public class Main { public static void main(String[] args) { HenshinResourceSet resourceSet = new HenshinResourceSet("model"); Module module = resourceSet.getModule("HelloWorld.henshin", false); EGraph graph = new EGraphImpl(resourceSet.getResource("MyModel2.xmi")); Engine engine = new EngineImpl(); UnitApplication app = new UnitApplicationImpl(engine); app.setEGraph(graph); app.setUnit(module.getUnit("main")); if (!app.execute(null)) { throw new RuntimeException("Execution error"); } resourceSet.saveEObject(graph.getRoots().get(0), "MyModel3.xmi"); } }
      
      







この堎合、より意味のある゚ラヌメッセヌゞが衚瀺される可胜性がありたす。



倉身倉換の䟋を芋るこずをお勧めしたす。 特にシェルピンスキヌの䞉角圢ず食事哲孊者に぀いお。



EMorF 、 AGG 、 VIATRAなど、同様のツヌルもいく぀かありたす。



おわりに



この蚘事では、いく぀かのモデル倉換ツヌルに泚目したした。



倉換自䜓もモデルであるず確信しおいたす。



カテゎリヌ理論SPO、DPOの興味深い実甚的な応甚を芋たした。これは埌で戻っおくるかもしれたせん。



もう䞀床、オブゞェクト管理グルヌプの仕様 XMI 、 OCL 、 QVT 、 UML に぀いお聞きたした。



䜕気なくEMF Compareモデル比范ツヌルに慣れたした。



゜ヌスコヌドはこちらから入手できたす 。



次の蚘事では、実際の耇雑なQVTo倉換に぀いお説明したす。



All Articles