看到eclipse里面的GMF 觉得比较有趣底层还是用到了EMF 花了两天时间仔细研究了以下EMF的确是个好东西 EMF根据ecore建模(可以和schema的xsd相互转换)生成强类型的EMF代码 这个强类型更强的地方是可以取得meta信息从而可以用于校验和界面辅助信息的生成类似于动态bean属性也可以根据名称动态取得 以前考虑过用xsd描述界面 但是数据载体只能是xml 即使利用apache的schema编译工具生成强类型的类后台代码也是xml 不利于持久化 emf在代码生成引擎比较智能可以标记出用户代码和自动生成代码不会有生成覆盖问题 这里做个简单示例: Ecore: 可以新建Ecore 建立好以后用GMF可视化编辑(EclipseRC) 生成Model: 点击myecore文件菜单:File>New>Other>Eclipse Modeling Framework>EMF Model 打开生成的mygenmodel 选择树顶点的:Generate Model Code 生成的代码里面会有一个编译错误 是中文编程的问题 中文没有大小写(先天不足啊)结果性别这个成员变量和性别类名混淆出错在错误代码前面加上包全名即可 利用生成的代码构建一个家庭输出xml并且校验之: import javaioIOException; import javautilIterator; import monutilDiagnostic; import monutilURI; import orgeclipseemfecoreEObject; import orgeclipseemfecoreresourceResource; import orgeclipseemfecoreutilDiagnostician; import orgeclipseemfecorexmiXMLResource; import orgeclipseemfecorexmiimplXMLResourceImpl; import orgsteevenfamilyFamilyFactory; import orgsteevenfamily人物; import orgsteevenfamily家庭; import orgsteevenfamily性别; public class TestMy { public static void main(String[]args) throws IOException { testFamily(); } private static void testFamily() throws IOException { 家庭family = FamilyFactoryeINSTANCEcreate家庭(); familysetTitle( steeven家 ); familyset老公(FamilyFactoryeINSTANCEcreate人物()); familyget老公()set姓名( steeven ); familyset老婆(FamilyFactoryeINSTANCEcreate人物()); familyget老婆()set姓名( stella ); familyget老婆()set性别(性别女_LITERAL); 人物sophie = FamilyFactoryeINSTANCEcreate人物(); sophieset姓名( sophie ); sophieset性别(性别女_LITERAL); familyget兔崽子()add(sophie); dump(family); validate(family); } private static void validate(EObjectfamily) { Diagnosticdiagnostic = DiagnosticianINSTANCEvalidate(family); Systemoutprintln(diagnostic); for (Iteratorit = diagnosticgetChildren(erator();ithasNext();) { Diagnosticdiag = (Diagnostic)itnext(); Systemoutprintln(diaggetMessage()); } } private static Resourcedump(EObjectobjs) throws IOException { // ResourceSetrs=newResourceSetImpl(); // rsgetResourceFactoryRegistry()getExtensionToFactoryMap()put( // ResourceFactoryRegistryDEFAULT_EXTENSION // newXMIResourceFactoryImpl()); // Resourceresource=rscreateResource(URI // createFileURI(c:\\temp\\testxml)); XMLResourceresource = new XMLResourceImpl(URI createFileURI( c:\\temp\\testxml )); resourcesetEncoding( GBK ); for (EObjectobj:objs) resourcegetContents()add(obj); // 目前版本不加入resource验证会报singling异常 resourcesave(Systemout null ); return resource; } } 运行结果如下: <? xmlversion=encoding=GBK ?> < family: 家庭xmlns:family = title =steeven家 老公 =/ 老婆 =/ 兔崽子 =/ /> DiagnosticERROR Thefeature老公oforgsteevenfamilyimpl家庭Impl@fa{file:/c:/temp/testxml#/}containsadanglingreferenceorgsteevenfamilyimpl人物Impl@eba{#//} Thefeature老婆oforgsteevenfamilyimpl家庭Impl@fa{file:/c:/temp/testxml#/}containsadanglingreferenceorgsteevenfamilyimpl人物Impl@cdef{#//} Thefeature兔崽子oforgsteevenfamilyimpl家庭Impl@fa{file:/c:/temp/testxml#/}containsadanglingreferenceorgsteevenfamilyimpl人物Impl@fd{#//} 可见输出的xml中没有包含人物的具体信息 修改myecore中老公/老婆/兔崽子属性的containment属性为true重新生成代码后运行结果如下: <?xmlversion=encoding=GBK?> <family:家庭xmlns:family=title=steeven家> <老公姓名=steeven/> <老婆性别=女姓名=stella/> <兔崽子性别=女姓名=sophie/> </family:家庭> DiagnosticOK ==================== EMF单独运行成功~ 这里ECORE似乎不支持嵌套定义不像schema那样一个complexType声明里面可以定义的很复杂 也不像Java的内部类 似乎被作了简化 更像关系数据库表之间的关系 待求证问题: EMF的校验信息是否支持国际化 EMF数据的能否更方便的保存到数据 EMF的灵活和强大已经验证过 用于C/S还是B/S应该都不是问题 |