用過EMF的人想必都對它的代碼產生功能印象深刻吧,有沒有想過這是怎樣實現的呢?
代碼產生一般是通過寫好的模板,在使用者輸入一些限制條件後,由程式把這兩者結合起來得到需要的代碼。EMF也是這樣,它內建了一些模板(放在 org.eclipse.emf.codegen.ecore裡),我們通過Java Interface或XML Schema檔案建立ecore模型後(這一步由org.eclipse.emf.codegen.ui支援),外掛程式 org.eclipse.emf.codegen幫我們產生model、edit、editor和test這幾個新的外掛程式,這些產生的外掛程式就可以被用來構 造應用程式了。
EMF使用JET(Java Emitter Templates)進行代碼產生,JET使用的模板檔案與JSP格式幾乎完全一致,像JSP裡有application這樣的隱含變數一樣,在JET模 板檔案裡可以使用argument這個隱含變數,它代表使用者的輸入參數(對EMF來說就是ecore模型)。下面是一個最簡單的帶有參數的模板檔案 hello.txtjet,JET模板檔案的副檔名一般是要組建檔案類型再加上jet。
<%@ jet package="hello" class="GreetingTemplate" %>Hello, <%=argument%>!
只要給這個模板檔案一個參數,JET就能幫我們產生一個字串,其內容是“Hello,參數!”。如果我們定義一個.javajet的模板,配合適當的參數,再把產生的字串儲存為檔案,就得到了java代碼,EMF的代碼產生過程就是如此。
自己實現代碼產生器的過程如下:建立一個Plugin項目,編寫模板檔案.javajet,一般放在templates目錄下;定義元模型,這個元 模型要與模板相匹配,模板的argument一般就是元模型最外層的container;構造一個使用者介面,讓使用者可以構造元模型的執行個體;提供一個 Action比如按鈕,使用者按下即開始產生代碼。
代碼的產生是由JETEmitter完成的,它會在workbench裡先產生一個.JETEmitter項目,把模板轉換為java類(這個過程類似JSP轉換為Servlet),然後調用這些類的generate()方法得到結果。
我做了一個產生.txt檔案的產生器外掛程式,點此下載。安裝後在Eclipse主菜單裡選File->New->Others,在New對話方塊裡選擇Sample Wizards下的Echo filename text file,建立的文字檔內容裡會包含檔案名稱。
因為用途有限,JET的資料不是很多,這裡有兩篇:連結1,連結2,其中後者在EMF的協助裡也找得到。
最後補充一個Tip,在plugin裡訪問一個相對路徑檔案的方法如下:
String base = Platform.getBundle(pluginId).getEntry("/").toString();String relativeUri = "templates/echo.txtjet";JETEmitter emitter = new JETEmitter(base + relativeUri, getClass().getClassLoader());
更正(08/23),上面說的方法只對JETEmitter有效,得到的路徑是Platform內部路徑而非本地路徑,這裡提供另一個方式可以得到本地路徑:
Platform.asLocalURL(Platform.getBundle(pluginId).getEntry("/log4j.properties"))