中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
使用 EMF 進行元建模:生成具體、可重用的 Java 代碼片段

EMF 是 Eclipse 平臺的主要部分,并且是一些相關(guān)技術(shù)和框架的基礎(chǔ),比如 Eclipse VisualEditor、SDO、XSD 和 UML — 其中的許多技術(shù)都被集成到 Rational? Application Developer 和WebSphere? Business Modeler 等 IBM? 平臺中?,F(xiàn)在,EMF 已經(jīng)吸收了許多 Java技術(shù)特性,比如枚舉類型、注釋和泛型。如果您還不熟悉 EMF,請參閱 參考資料 中的文章獲得入門知識。

在大多數(shù)文檔和教程中,EMF 都被用于建模數(shù)據(jù)接口(比如 EMF 發(fā)行文檔中的 LibraryBooks),而不用于建模行為。當(dāng)然,還有一些針對數(shù)據(jù)對象生成的默認(rèn)方法實現(xiàn),但這些實現(xiàn)涉及到模型元素之間的關(guān)系。而且,將 EMF 用作 “元模型” 的經(jīng)過歸檔的示例非常少 —除了 Eclipse Foundation 文章 “Modeling Rule-Based Systems with EMF”(參見 參考資料)— 但是這個示例并沒有展示如何擴展 Ecore 元模型。

最后,使用和擴展 EMF JET 模板的過程也沒有被很好地進行歸檔。此外,JET Editor 項目最近已經(jīng)遷移到另一個Eclipse 項目(M2T)上。本文旨在澄清這些問題,并使您能夠在 EMF 上下文中使用動態(tài)模板實現(xiàn)更多的功能。因此,本文假設(shè)您對 EMF有基本的了解。

為什么要擴展 Ecore 元模型?

Ecore 究竟是什么?

Eclipse Modeling Framework (EMF) 是 Eclipse 的一個建??蚣?。根據(jù) Eclipse Foundation的定義,核心 EMF 框架包括一個描述模型的元模型(Ecore)和模型的運行時支持,包括更改通知、對默認(rèn) XMI 序列化的持久性支持和用于對EMF 對象執(zhí)行常規(guī)操作的反射 API(reflective API)。換句話說,Ecore定義核心模型的結(jié)構(gòu),而核心模型定義開發(fā)人員用于維護應(yīng)用程序數(shù)據(jù)的模型結(jié)構(gòu)。

Ecore 元模型是一個強大的工具,可用于設(shè)計模型驅(qū)動架構(gòu)(Model-Driven Architecture,MDA),后者可以作為軟件開發(fā)的起點。通常情況下,我們定義應(yīng)用程序范圍內(nèi)的對象(EClass 類型)、對象屬性以及它們之間的關(guān)系。我們還使用 EOperation 模型元素定義屬于這些對象的特定操作。默認(rèn)情況下,EMF 將會為這些操作生成骨架 或方法簽名,但是我們必須返回并實現(xiàn)這些操作,常常要反復(fù)地重新編寫類似的邏輯。

但是,如果我們想在模型中指定某種任意的實現(xiàn)行為該怎么辦呢?一種方法是添加基于文本的注釋(EAnnotation 類型),以建模對象并在代碼生成期間解釋模板中的這些注釋。關(guān)于這種方法的出色示例,可以查閱 Eclipse Foundation 文章 “Implementing Model Integrity in EMF with MDT OCL”(參見 參考資料)。但是,正如這篇文章中所描述的,我們的目標(biāo)不是驗證模型元素,而是對實現(xiàn)本身進行建模,以使任何具體的模型能夠重用這些元模型元素。為此,我們需要擴展 Ecore 元模型。


擴展了的元模型

本文附帶了一個高度簡化的用來擴展 Ecore 的編程式模型。它不是一個完整或連貫的元模型或框架;嚴(yán)格來講,它是一個元素的原型集合,用于演示使用 EMF 對代碼實現(xiàn)進行元建模的能力。圖 1 顯示了我們的擴展元模型示例 EcoreX 的快照,下面是每個元素的簡短描述。


圖 1. EcoreX 模型


EcoreX 元素

EPackageX 擴展 EPackage
這是 Ecore 元素 EPackage 的一個簡單 “標(biāo)記” 擴展,沒有任何附加屬性。這個元素是必需的,因為在默認(rèn)情況下,元素 EPackage EMF 編輯器插件不允許將EClass 的子類作為子元素添加(參閱下面的 EClassX)。通過提供一個可擴展EPackage 的模型元素,代碼將會自動生成,從而允許將一個 EClassX 子元素添加到 EPackageX 中。
EClassX 擴展 EClass
同樣地,這是 Ecore 元素 EClass 的一個簡單標(biāo)記擴展,沒有任何附加屬性。與上面的元素類似,此元素也是必需的,因為在默認(rèn)情況下,EClass 的編輯器插件不允許添加 EOperation 的子類 — 這正是我們要在本文中實現(xiàn)的目標(biāo)。
EOperationImpl 擴展 EOperation
這是用于向 Ecore 模型添加具體的元功能的基本實體和入口點。此元素被賦予 Ecore 的基礎(chǔ) EOperation 元素中沒有的屬性。下面描述的所有其他元素都屬于EOperationImpl 并用于構(gòu)成編程式實現(xiàn)。例如,EOperationImpl 包含變量和語句,可以返回一個引用或值。
LocalVariable 擴展 ETypedElement
LocalVariable 是一個本地變量。變量包含一個名稱和一個 Java 類型(比如 String、Integer、Object),而且由于這些屬性已經(jīng)存在于其超級超類(super-superclass)EParameter 中,所以 LocalVariable 不需要額外屬性。
Statement 擴展 EClass
在我們的簡化邏輯模型中,一個 EOperationImpl 包含許多將會按給定順序計算的statementStatement 是一個抽象超類。
LiteralAssignment 擴展 Statement
LiteralAssignment 引用一個變量,并且有一個 String 屬性,允許用戶輸入一個要被解析的值并將其分配給一個變量(例如,“hello”、“4.5” 可以分別分配給 Stringfloat)。
Access 擴展 Statement
Access 表示引用 Java 字段或操作的動作。
FieldReferenceAssignment 擴展 Access
訪問一個字段,以分配一個值(例如,var1 =var2.name)。
Invoke 擴展 Access
調(diào)用一個操作(Java 方法)。Invoke 的結(jié)果可以分配給一個變量(例如,myVar = obj.toString())。

圖 2 展示了 EcoreX 元模型的一種更加類似 UML 的表示。


圖 2. Ecorex 模型圖



入門

本文包括六個高級的步驟:

  1. 擴展 Ecore 元模型,添加新語義
  2. 為被擴展的元模型創(chuàng)建一個 genmodel
  3. 為此元模型生成一個 EMF 編輯器,并作為插件安裝。
  4. 使用這個新編輯器,構(gòu)建一個具體的模型來描述編程行為。
  5. 為這個具體的模型創(chuàng)建并配置一個 genmodel。
  6. 基于這個具體的模型生成具體的 Java 代碼。

可以創(chuàng)建或?qū)肷厦婷枋龅脑P汀煞N情況都需要從一個現(xiàn)有 EMF 項目或創(chuàng)建一個新項目入手(New > Other > Eclipse Modeling Framework > Empty EMF Project)。我們的項目名為 EMFX,并且它應(yīng)包含一個名為 model 的文件夾。可以將這個 EcoreX.ecore 模型(參見 參考資料)復(fù)制到 model 目錄并跳至 構(gòu)建和啟動 Editor Metamodel 插件 小節(jié),也可以執(zhí)行以下步驟,從頭創(chuàng)建一個元模型。

擴展 Ecore 元模型 — 從頭開始

右鍵單擊項目,從上下文菜單中選擇 New > Other >Example EMF Model Creation Wizards > Ecore Model。(對于 Eclipse V3.5+ [Galileo,Helios],則應(yīng)選擇 New > Other > Eclipse Modeling Framework > EcoreModel。)選擇 model 文件夾和名稱 EcoreX.ecore。

默認(rèn)情況下,我們將模型包稱為 ecorex。在模型窗口中右鍵單擊并選擇 Load Resource > Browse Registered Packages。選擇具有名稱空間 http://www.eclipse.org/emf/2002/Ecore 的 Ecore Model。

導(dǎo)入 Ecore 元模型之后,就可以對其進行擴展了。要重新創(chuàng)建 ecorex.ecore 模型,首先在包元素 ecorex 上右鍵單擊并選擇 New Child EClass。將此元素稱為 EPackageX(參閱上面的模型元素描述)。然后需要將基元素 EPackage 作為這個新元素的 ESuper Type 添加。

通過將 EClass 指定為 ESuperType,使用相同的過程創(chuàng)建新元素 EClassX。根據(jù)需要對 Ecore 對象劃分子類,在 EcoreX 模型中繼續(xù)定義其他 EClass。使用圖 1 和 EcoreX.ecore 文件了解要為哪個 EClass 創(chuàng)建什么屬性。

構(gòu)建并啟動the Editor Metamodel 插件

I在構(gòu)建步驟中,我們將創(chuàng)建元模型 genmodel 并構(gòu)建模型和編輯器項目。右鍵單擊 EcoreX 項目并選擇 New > Other >Eclipse Modeling Framework > EMF Model。(對于 EMF V2.5+ [Galileo, Helios],則應(yīng)選擇 New > Other > Eclipse Modeling Framework > EMFGenerator Model。)可以提供一個名稱或接受默認(rèn)的名稱 EcoreX.genmodel。EcoreX 模型應(yīng)該被預(yù)選擇為 genmodel 的基模型。單擊 Load 驗證EcoreX.ecore 元模型。


圖 3. 新 EMF 模型


當(dāng)要求指定要生成和從其他生成器模型引用的包時,選擇 Root packages 下面的 EcoreX 包和 Referenced generator models 下面的 Ecore。

現(xiàn)在,向?qū)樵P蛣?chuàng)建一個 genmodel。突出顯示 genmodel 中的頂級元素之后,從上下文菜單中選擇 Generate All,這樣可以自動生成關(guān)聯(lián)的代碼。根據(jù)在 genmodel 中配置的行為,這將生成 4 個 Eclipse 項目。本文不會關(guān)注 .test 項目,所以您可能不希望生成這個插件。

現(xiàn)在我們繼續(xù)啟動步驟。在大多數(shù) Eclipse 教程中,都會要求您在單獨的 Eclipse過程中啟動所開發(fā)的插件。在本節(jié)中,我們將采用一種不同的方法:我們將在當(dāng)前 Eclipse和工作區(qū)中激活插件。這樣更容易將預(yù)構(gòu)建的元模型與下一節(jié)中具體的模型開發(fā)集成。為此:

  1. 雙擊 EMFX plugin.xml 打開插件配置編輯器。
  2. 單擊 Exporting 選項卡下的 Export Wizard。
  3. 選擇基本的建模插件和兩個編輯器插件。
  4. Destination 選項卡下,選擇 Eclipse 安裝目錄,或托管存儲庫(如果可用)。

圖 4. 導(dǎo)出


注意:如果使用 –console 選項啟動 Eclipse,您可以使用 OSGi 命令控制臺動態(tài)地啟動、停止、更新和刷新插件(插件組),無需重新啟動 Eclipse 或啟動一個單獨的實例。

單擊 Finish 時,會自動構(gòu)建生成的插件 JAR 文件,并自動將其復(fù)制到插件目錄。此時,您需要重新啟動 Eclipse,激活新插件。現(xiàn)在我們已經(jīng)準(zhǔn)備好啟動編輯器插件了,創(chuàng)建一個新項目來保存我們的具體模型(我們的模型命名為 Test2)。

在這個新項目中,導(dǎo)航到 New > Other Example EMF Model CreationWizards > Ecorex Model 并提供一個模型名稱。注意:在 EMF 的最新版本 (V2.5+) 中,具體模型的文件擴展名必須被設(shè)為 .ecore,而不是 .ecorex;否則,這個具體的 genmodel 將不能在后續(xù)步驟中被成功創(chuàng)建。選擇 EPackageX 元素。您現(xiàn)在有了一個空的具體模型。后續(xù)小節(jié)將討論如何構(gòu)建這些編程模型元素;完成后的文件 My.ecore 可以在 參考資料 部分找到。


建模具體的測試模型

在本節(jié)中,我們將對一個具體的 Java 類(EClassX 的實例)進行建模,這個類包含兩個具體的方法,我們將對這兩個方法的實現(xiàn)進行建模。第一個示例方法接受 String 參數(shù)消息,并輸出消息和一個時間戳 — 這有利于調(diào)試消息。以下是期望結(jié)果的表示。


清單 1. printTimestampMessage
            void printTimestampMessage(String message) {            System.out.print(message);            System.out.print("; Timestamp= ");            System.out.println(System.currentTimeMillis());            }            

第二個示例接受 3 個基于日期的參數(shù),并返回一個數(shù)字值,表示該日期對應(yīng)的是星期幾。


清單 2. getDayOfWeek
            int getDayOfWeek(int year, int month, int date) {            int result;            Calendar calendar = Calendar.getInstance();            calendar.set(year, month, date);            result = calendar.get(Calendar.DAY_OF_WEEK);            return result;            }            

第一步是填入在上一節(jié)最后一步中創(chuàng)建的新 EPackageX 元素下的 3 個必需屬性。如果在建模窗口下看不到 Properties 選項卡,可以從上下文菜單中選擇 Show Properties View。在這個示例中,我們的包名為 mypackage。


圖 5. EPackageX 屬性


接下來,向 mypackage 添加一個新 EClassX??梢栽?mypackage 突出顯示時使用上下文菜單完成此任務(wù)。填入 name 屬性,為類提供一個名稱(比如 MyClass),向新類添加兩個 EOperationImpl 元素,并為它們指定方法名 printTimeStampMessagegetDayofWeek。然后,向每一個操作添加 Ecore 參數(shù)。


圖 6. EOperationImplgetDayOfWeek()



圖 7. getDayOfWeek() 屬性


上面的操作 printTimestampMessage() 接受一個 EString 類型的參數(shù),而 getDayOfWeek() 接受 3 個 EInt 類型的參數(shù)。此外,操作 getDayOfWeek 返回一個 EInt,這可以在 property 屬性 EType 下進行配置(參見圖 7)。

剖析 EOperationImpl

到現(xiàn)在為止,我們僅使用了繼承的 Ecore 元素和屬性?,F(xiàn)在是時候使用我們擴展的元模型元素來構(gòu)建 Java 實現(xiàn)了。

LocalVariable
查看一下圖 8,printTimestampMessage() 將需要兩個 LocalVariable 元素 — 一個為EString 類型,另一個為 ELong 類型。

圖 8. printTimestampMessage()



圖 9. LiteralAssignment


在圖 9 中,Value 屬性的字符串被內(nèi)聯(lián)到 LiteralAssignment。您可以設(shè)想一個不同的元模型,其中的文字值(常量)被建模為單獨的元素。

接下來,我們插入一個 LiteralAssignment 類型的元素,它允許選擇一個 LocalVariable 并為其分配值。在本例中,我們選擇 String 變量并提供上面的原型方法中的文本值(記住在文本兩邊加上引號)。

DataType
再次查看上圖,注意,有一個名為 SystemType 的 Ecore DataType,它是 java.lang.System 的一個包裝器。必須將其添加到我們的 mypackage 包,因為它將會被隨后的 Invoke 元素引用。
Statement
添加到這個操作的第一個 StatementSystemType 中的靜態(tài)方法 currentTimeMillis() 的一個 Invoke,已經(jīng)在上面定義了。

圖 10. 調(diào)用 currentTimeMillis() 屬性


根據(jù)我們的元模型(我們將在下一節(jié)提供代碼模板),上面的 Invoke 將轉(zhuǎn)換為 Java 語句:timestamp = java.lang.System.currentTimeMillis();。

下一個 Invoke 與之前的那個稍有不同。首先,沒有 Assignment。其次,我們將把 message 參數(shù)的引用作為 Args 屬性的一個參數(shù)。


圖 11. 調(diào)用 out.print 屬性


另外請注意,Access Name 屬性的值為out.print— 在這里我們實際上從 Java System 間接引用了字段 out,然后調(diào)用方法 print。我們使用了這種快捷方式,而沒有結(jié)合使用一個 FieldReferenceAssignment 和一個 PrintStream 類型的 LocalVariable

操作中的第 3 個(最后一個)Invoke 是一個使用 LocalVariabletimestamp 作為單個參數(shù)的 println()。這就完成了具體操作 printTimestampMessage() 的建模。

讓我們看看第二個 EOperationImplgetDayOfWeek() 的完整模型。


圖 12. getDayOfWeek()


DataTypes
在模型的底部,我們創(chuàng)建了一個額外的 DataType,名為 CalendarType,這是該操作所必需的。
LocalVariables
在操作模型的 3 個 LocalVariable 中,我們主要關(guān)注稱為 resultLocalVariable,因為它將會保存執(zhí)行完操作的最后一條語句之后返回的值。在 EOperationImpl 屬性中有一個名為 Return Ref 的屬性,而且在我們的實現(xiàn)中,我們使用下拉菜單選擇 LocalVariable 結(jié)果。
Statement
正如圖 12 所示,3 個 LocalVariable 之后是 3 個 Statement。第一個是 Invoke,它使用 CalendarType 元素上的 getInstance(),為 calendar 變量分配一個值,與圖 10 中的操作類似。

接下來是對 calendar 變量執(zhí)行的 set() 方法的 Invoke,現(xiàn)在它傳遞 3 個與 EOperationImpl 參數(shù)(yearmonthdate)相對應(yīng)的 Arg。


圖 13. 帶有參數(shù)的 set()



圖 14. FieldReferenceAssignment


根據(jù)我們的元模型,這個元素將會生成與 DAY = Calendar.DAY_OF_WEEK; 類似的 Java 代碼。

在圖 15 中,DAY 變量用于這個 EOperationImpl 的最后一個 Invoke:一個 get(),其返回值被分配給變量 result(我們的實現(xiàn)的 Return Ref


圖 15. Return Ref
 

實現(xiàn)動態(tài)模板

我們現(xiàn)在設(shè)計了一個擴展的元模型,并用其描述了一個具體的模型 My.ecore(請參見上述的 EMF V2.5+文件名稱說明)?,F(xiàn)在終于可以用 JET 最終實現(xiàn)一些代碼實現(xiàn)了。要查看 JET 模板的語法突出顯示功能,您需要安裝 JET EditorPlugin(參見 參考資料 和 “JET Editor 局限性”)。

默認(rèn)情況下,在為模型生成代碼時,EMF 不會使用動態(tài)模板。它使用預(yù)構(gòu)建的 Java 類。要開始定制 JET 模板,我們需要從插件 JAR 文件 org.eclipse.emf.codegen.ecore_2.3.0.XYZ.jar 復(fù)制一些文件,其中 XYZ 是 Eclipse 插件文件夾中您的 EMF 版本的時間戳。本文使用 org.eclipse.emf.codegen.ecore_2.3.0.v200706262000.jar。要復(fù)制這些文件,請使用任意一種解壓縮工具打開 JAR 文件,并執(zhí)行以下操作:

  1. 從這個 JAR 文件將模板目錄提取到您的具體模型的 Java 項目中。
  2. 在模板/模型中創(chuàng)建一個目錄,名為 Class。
  3. Class 文件夾中創(chuàng)建一個新的空文件,名為 implementedGenOperation.TODO.override.javajetinc 或從 參考資料 中復(fù)制。

由名稱可以看出,第 3 步中的新文件是一個 JET 模板,我們將在其中加入模型對象 EOperationImpl 的代碼生成邏輯。默認(rèn)情況下,這個文件并不存在,因為 EMF 只為每個 EOperation 提供一個空的方法簽名。一旦激活了動態(tài)模板功能,我們的新文件將被作為 Java 方法體自動包括,正如 EOperationImpl 所定義的。

以下是 implementedGenOperation.TODO.override.javajetinc 的完整代碼。


清單 3. implementedGenOperation
            // created by implementedGenOperation.TODO.override.javajetinc            <%            if ( ! (genOperation.getEcoreOperation() instanceof EOperationImpl) ) { %>            // TODO: implement this method            // Ensure that you remove @generated or mark it @generated NOT            throw            new UnsupportedOperationException();            <% } else { %>            // ** EOperationX implementation **            <% EOperationImpl opx = (EOperationImpl)genOperation.getEcoreOperation();            Statement stm = null;            Iterator iterator = null;            EList<LocalVariable> pList = opx.getLocalVariables();            LocalVariable lvar = null;            String iname = null;            StringBuffer paramsString = null;            StringBuffer varString = null;            for (int i = 0;i < pList.size(); i++) {            lvar = pList.get(i);            iname = lvar.getEType().getInstanceClassName();%>            <%=iname%>            <%=lvar.getName()%><%            if (iname.startsWith("java")) { %> = null            <% } %>;            <% }            iterator = opx.getStatements().iterator();            while (iterator.hasNext()) {            paramsString = new StringBuffer();            varString = new StringBuffer();            iname = null;            stm = (Statement)iterator.next();            if (stm instanceof LiteralAssignment) {%>            <%= stm.getAssignment().getName()%> = <%=            ((LiteralAssignment)stm).getValue()%>;            <%} else            //            if (stm instanceof FieldReferenceAssignment) {            Access ax = (Access)stm;            if (stm.getAssignment() != null) {            varString.append(stm.getAssignment().getName());            varString.append(" = ");            }            if ( ax.getStaticType() != null) {            // STATIC            iname = ax.getStaticType().getInstanceClassName();            } else {            // NON STATIC            iname = ax.getTarget().getName();            } %>            <%=varString.toString()%><%=iname%>.<%=ax.getAccessName()%>;            <% } else            if (stm instanceof Invoke) {            // INVOKE            Invoke iv = ((Invoke)stm);            if (stm.getAssignment() != null) {            varString.append(stm.getAssignment().getName());            varString.append(" = ");            }            for (int p = 0; p < iv.getArgs().size(); p++) {            paramsString.append(iv.getArgs().get(p).getName());            if ( p + 1 < iv.getArgs().size() ) {            paramsString.append(" , ");            }            }            if (iv.getStaticType() != null) {            // STATIC            iname = iv.getStaticType().getInstanceClassName();            } else {            // NON STATIC            iname = iv.getTarget().getName();            } %>            <%=varString.toString()%><%=iname%>.<%=iv.getAccessName()            %>(<%=paramsString.toString()%>);            <% }            } // STATEMENTS            if (opx.getReturnRef() != null) { %>            return            <%=opx.getReturnRef().getName()%>;            <% }            } // EOPERATIONIMPL %>            

對 JET 的詳細討論超出了本文的范圍。但是,因為 JET 模板對我們的操作過程至關(guān)重要,我們將在偽代碼方面回顧一下模板的內(nèi)容。請記住,在處理模板之前,第一個變量 genOperation 已經(jīng)被 Ecore/JET 預(yù)初始化。


清單 4. genOperation 被 Ecore/JET 預(yù)初始化
            Is this GenOperation is an EOperationImpl?            If false, emit default UnsupportedOperationException            STOP;            Else, cast it to EOperationImpl;            continue;            Find and declare all elements of type LocalVariable, initializing Java Objects to null;            Iterate through all Statements;            Emit Java code according to the subtype;            Does the implementation return something?            If yes, emit the return statement;            

在構(gòu)建具體模型之前,需要執(zhí)行一些操作。首先,在 templates/model/Class.javajet 頂部,我們必須將以下內(nèi)容添加到導(dǎo)入列表(標(biāo)記為粗體的前兩行):

				<%@            jet            package="org.eclipse.emf.codegen.ecore.templates.model"            imports="ecorex.*  org.eclipse.emf.common.util.*             java.util.* org.eclipse.emf.codegen.ecore.genmodel.*"…            

當(dāng)然,EcoreX 包是經(jīng)過擴展的元模型。接下來,我們需要為我們的具體模型(My.ecore,類型為 '.ecorex')創(chuàng)建和配置一個 EMF(GenModel)。為此,在模型上右鍵單擊并選擇 New > Other > Eclipse Modeling Framework > EMF Model(對于 EMF V2.5+ [Galileo, Helios],應(yīng)選擇 New > Other >Eclipse Modeling Framework > EMF Generator Model。)創(chuàng)建完成之后,需要在屬性組 Templates &Merge 下配置 3 個屬性,在 Model 下配置第四個屬性。


圖 16. GenModel— Templates & Merge


  1. Dynamic Templates 設(shè)置為 true。
  2. 指定 Template Directory。
  3. 將 EMFX(擴展的元模型插件 ID)添加到 Template Plug-in Variables
  4. 最近版本:在 Model 組屬性下,將 Suppress Interfaces 設(shè)置為 true。

現(xiàn)在可以進行構(gòu)建了,右鍵單擊 GenModel 并選擇 Generate Model Code。如果一切順利,在具體的 Test 項目(我們的項目稱為 Test2)的源文件夾(src)中,您應(yīng)該可以看到生成的 Java源代碼包和類,其中一個名為 mypackage.impl.MyClassImpl.java。打開該文件,您應(yīng)該會看到兩個生成的方法。


清單 5. MyClassImpl.java
            public            void printTimestampMessage(String message) {            // created by implementedGenOperation.TODO.override.javajetinc            // ** EOperationX implementation **            java.lang.String timestampStr = null;            long timestamp;            timestampStr = "; Timestamp = ";            timestamp = java.lang.System.currentTimeMillis();            java.lang.System.out.print(message);            java.lang.System.out.print(timestampStr);            java.lang.System.out.println(timestamp);            }            public            int getDayOfWeek(int year, int month, int date) {            // created by implementedGenOperation.TODO.override.javajetinc            // ** EOperationX implementation **            int result;            int DAY;            java.util.Calendar calendar = null;            calendar = java.util.Calendar.getInstance();            calendar.set(year , month , date);            DAY = java.util.Calendar.DAY_OF_WEEK;            result = calendar.get(DAY);            return result;            }            

可以添加一個 main 方法測試這個類。

警告和故障診斷

Ecore 文件命名 (EMF V2.5+)

在 EMF V2.5 之前,正如上面的幾個屏幕快照所示,從一個擴展了的 Ecore 模型生成的具體模型應(yīng)該保留'.ecorex' 的擴展名(如創(chuàng)建時的向?qū)ㄗh的那樣)。這有助于區(qū)別擴展了的模型與 ‘初級的’ Ecore 模型。然而,在 EMF的最新版本中,genmodel 向?qū)Вㄈ缭趫D 16 之前所解釋的)不接受除 .ecore 之外的其他文件擴展名。

JET Editor 局限性

要獲得 JET 模板的語法突出顯示功能,您需要安裝 Eclipse JET Editor(JET Editor Plugin 最近已經(jīng)從 EMF 遷移到 M2T)。

但是,在撰寫本文時,JET Editor 的最新版本不能正確處理 Java 內(nèi)容幫助或嵌套 JET 包含文件(比如.javajetinc 文件)的動態(tài)編譯。此外,為了確保構(gòu)建成功,只能在父文件(比如上面的Class.javajet)中指定導(dǎo)入操作,而不能在包含的文件中指定。

實際上,使用一些額外配置(即,使用項目的上下文菜單),您可以將 EMF 動態(tài)模板項目(本文示例中的 Test2)轉(zhuǎn)換為 JET 項目。在實踐中,上面提及的局限性以及 EMF 和 M2T/JET 之間缺少集成,使得這種方法不太可行。

因此,很難捕獲和改正包含的模板文件中的錯誤。由于在生成最終代碼之前,JET 模板首先會被編譯為一種中間 Java文件(默認(rèn)情況下位于一個隱藏的 Java 項目 JETEmitter 中),所以通過從 Eclipse 的 Package Explorer視圖中刪除過濾器,您能夠看到這些編譯錯誤。如果這只是模板文件中的格式錯誤,在構(gòu)建期間將會出現(xiàn)一個 Eclipse 彈出窗口?;蛟S在未來的 JET版本中,我們會看到更多的改進功能。

未進行模型驗證

本文中的示例未使用 EMF Validation Framework 或 OCL 功能。所以,模型中的不一致性將會導(dǎo)致構(gòu)建失敗,例如,一個 EOperationImpl 可以聲明某種返回類型,但是Return Ref 屬性可以引用不同的類型或者為空。在構(gòu)建模型期間,將不會發(fā)現(xiàn)這些錯誤,而且生成的代碼將無法編譯??梢詫υP瓦M行改進,使用 OCL 增強完整性和約束(參見 參考資料)。

結(jié)束語

我們看到了如何擴展 Ecore 元模型,將合成的 Java 方法中的編程式行為概念化。通過導(dǎo)入 Ecore 本身,我們擴展了一些 Ecore 模型元素— 尤其是 EOperation。然后構(gòu)建了元模型,并使用編輯器設(shè)計了一個具體的測試模型,包括以 EOperationImpl 形式建模的兩個 Java 方法。我們配置并構(gòu)建了 JET 模板,用于為 EOperationImpl 生成代碼。


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
基于 GMF 的流程分析工具的設(shè)計與實現(xiàn)
eclipse EMF介紹系列(EMF與MDA)
淺析Eclipse建??蚣?EMF)及其動態(tài)能力 中國站長網(wǎng)絡(luò)學(xué)院
深入淺出Eclipse Modeling Framework (EMF)
探索模型驅(qū)動開發(fā) (MDD) 和相關(guān)方法,將領(lǐng)域特定建模應(yīng)用于模型驅(qū)動的體系結(jié)構(gòu)(轉(zhuǎn)IBM)
15 分鐘學(xué)會 Eclipse GMF
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服