看到eclipse裡面的GMF 覺得比較有趣底層還是用到了EMF 花了兩天時間仔細研究了以下EMF的確是個好東西
EMF根據ecore建模(可以和schema的xsd相互轉換)生成強類型的EMF代碼 這個強類型更強的地方是可以取得meta信息從而可以用於校驗和界面輔助信息的生成類似於動態bean屬性也可以根據名稱動態取得
以前考慮過用xsd描述界面 但是數據載體只能是xml 即使利用apache的schema編譯工具生成強類型的類後台代碼也是xml 不利於持久化 emf在代碼生成引擎比較智能可以標記出用戶代碼和自動生成代碼不會有生成覆蓋問題
這裡做個簡單示例:
Ecore:
可以新建Ecore 建立好以後用GMF可視化編輯(EclipseRC)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221228.jpg)
生成Model:
點擊myecore文件菜單:File>New>Other>Eclipse Modeling Framework>EMF Model
打開生成的mygenmodel 選擇樹頂點的:Generate Model Code
生成的代碼裡面會有一個編譯錯誤 是中文編程的問題 中文沒有大小寫(先天不足啊)結果性別這個成員變量和性別類名混淆出錯在錯誤代碼前面加上包全名即可
利用生成的代碼構建一個家庭輸出xml並且校驗之:
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import java
io
IOException;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import java
util
Iterator;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import mon
util
Diagnostic;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import mon
util
URI;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
eclipse
emf
ecore
EObject;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
eclipse
emf
ecore
resource
Resource;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
eclipse
emf
ecore
util
Diagnostician;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
eclipse
emf
ecore
xmi
XMLResource;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
eclipse
emf
ecore
xmi
impl
XMLResourceImpl;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
steeven
family
FamilyFactory;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
steeven
family
人物;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
steeven
family
家庭;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
import org
steeven
family
性別;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221291.gif)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221278.gif)
public class TestMy
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
{
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221256.gif)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221272.gif)
public static void main(String[] args) throws IOException
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
{
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
testFamily();
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221240.gif)
}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221272.gif)
private static void testFamily() throws IOException
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
{
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
家庭 family = FamilyFactory
eINSTANCE
create家庭();
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
setTitle(
steeven家
);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
set老公(FamilyFactory
eINSTANCE
create人物());
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
get老公()
set姓名(
steeven
);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
set老婆(FamilyFactory
eINSTANCE
create人物());
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
get老婆()
set姓名(
stella
);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
get老婆()
set性別(性別
女_LITERAL);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
人物 sophie = FamilyFactory
eINSTANCE
create人物();
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
sophie
set姓名(
sophie
);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
sophie
set性別(性別
女_LITERAL);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
family
get兔崽子()
add(sophie);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
dump(family);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
validate(family);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221240.gif)
}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221272.gif)
private static void validate(EObject family)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
{
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
Diagnostic diagnostic = Diagnostician
INSTANCE
validate(family);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
System
out
println(diagnostic);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221256.gif)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221272.gif)
for (Iterator it = diagnostic
getChildren(erator(); it
hasNext();)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
{
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
Diagnostic diag = (Diagnostic) it
next();
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
System
out
println(diag
getMessage());
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221240.gif)
}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221240.gif)
}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221272.gif)
private static Resource dump(EObject
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
objs) throws IOException
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221253.gif)
{
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
// ResourceSet rs = new ResourceSetImpl();
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
// rs
getResourceFactoryRegistry()
getExtensionToFactoryMap()
put(
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
// Resource
Factory
Registry
DEFAULT_EXTENSION
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
// new XMIResourceFactoryImpl());
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
// Resource resource = rs
createResource(URI
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
//
createFileURI(
c:\\temp\\test
xml
));
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
XMLResource resource = new XMLResourceImpl(URI
createFileURI(
c:\\temp\\test
xml
));
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
resource
setEncoding(
GBK
);
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
for (EObject obj : objs)
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
resource
getContents()
add(obj); // 目前版本不加入resource驗證會報singling異常
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
resource
save(System
out
null );
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221282.gif)
return resource;
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221240.gif)
}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221285.gif)
}
運行結果如下:
<? xml version=
encoding=
GBK
?>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
< family: 家庭 xmlns:family =
title =
steeven家
老公 =
/
老婆 =
/
兔崽子 =
/
/>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
Diagnostic ERROR
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
The feature
老公
of
org
steeven
family
impl
家庭Impl@f
a
{file:/c:/temp/test
xml#/}
contains a dangling reference
org
steeven
family
impl
人物Impl@
eb
a{#//}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
The feature
老婆
of
org
steeven
family
impl
家庭Impl@f
a
{file:/c:/temp/test
xml#/}
contains a dangling reference
org
steeven
family
impl
人物Impl@
cd
e
f{#//}
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
The feature
兔崽子
of
org
steeven
family
impl
家庭Impl@f
a
{file:/c:/temp/test
xml#/}
contains a dangling reference
org
steeven
family
impl
人物Impl@
f
d{#//}
可見輸出的xml中沒有包含人物的具體信息
修改my
ecore中老公/老婆/兔崽子屬性的containment屬性為true
重新生成代碼後運行結果如下:
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
<?xml version=
encoding=
GBK
?>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
<family:家庭 xmlns:family=
title=
steeven家
>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
<老公 姓名=
steeven
/>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
<老婆 性別=
女
姓名=
stella
/>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
<兔崽子 性別=
女
姓名=
sophie
/>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
</family:家庭>
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112320221267.gif)
Diagnostic OK
====================
EMF單獨運行成功~
這裡ECORE似乎不支持嵌套定義
不像schema那樣一個complexType聲明裡面可以定義的很復雜
也不像Java的內部類
似乎被作了簡化
更像關系數據庫表之間的關系
待求證問題:
EMF的校驗信息是否支持國際化
EMF數據的能否更方便的保存到數據
EMF的靈活和強大已經驗證過
用於C/S還是B/S應該都不是問題
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28388.html