看到eclipse3.2里面的GMF, 觉得比较有趣,底层还是用到了EMF. 花了两天时间仔细研究了以下EMF,的确是个好东西.
EMF根据ecore建模(可以和schema的xsd相互转换)生成强类型的EMF代码. 这个强类型更强的地方是可以取得meta信息,从而可以用于校验和界面辅助信息的生成.类似于动态bean,属性也可以根据名称动态取得.
以前考虑过用xsd描述界面, 但是数据载体只能是xml, 即使利用apache的schema编译工具生成强类型的类,后台代码也是xml. 不利于持久化. emf在代码生成引擎比较智能,可以标记出用户代码和自动生成代码.不会有生成覆盖问题.
这里做个简单示例:
1. Ecore:
可以新建Ecore, 建立好以后用GMF可视化编辑(Eclipse3.2RC2)
2. 生成Model:
点击my.ecore文件,菜单:File->New->Other->Eclipse Modeling Framework->EMF Model
3. 打开生成的my.genmodel, 选择树顶点的:Generate Model Code
生成的代码里面会有一个编译错误. 是中文编程的问题, 中文没有大小写(先天不足啊),结果性别这个成员变量和性别类名混淆,出错.在错误代码前面加上包全名即可.
4. 利用生成的代码构建一个家庭,输出xml并且校验之:
Word-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee" twffan="done"
import java.io.IOException; import java.util.Iterator; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.ecore.xmi.XMLResource; import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl; import org.steeven.family.FamilyFactory; import org.steeven.family.人物; import org.steeven.family.家庭; import org.steeven.family.性别; public class TestMy { public static void main(String[] args) throws IOException { testFamily(); } PRivate static void testFamily() throws IOException { 家庭 family = FamilyFactory.eINSTANCE.create家庭(); family.setTitle( " steeven家 " ); family.set老公(FamilyFactory.eINSTANCE.create人物()); family.get老公().set姓名( " steeven " ); family.set老婆(FamilyFactory.eINSTANCE.create人物()); family.get老婆().set姓名( " stella " ); family.get老婆().set性别(性别.女_LITERAL); 人物 sophie = FamilyFactory.eINSTANCE.create人物(); sophie.set姓名( " sophie " ); sophie.set性别(性别.女_LITERAL); family.get兔崽子().add(sophie); dump(family); validate(family); } private static void validate(EObject family) { Diagnostic diagnostic = Diagnostician.INSTANCE.validate(family); System.out.println(diagnostic); for (Iterator it = diagnostic.getChildren().iterator(); it.hasNext();) { Diagnostic diag = (Diagnostic) it.next(); System.out.println(diag.getMessage()); } } private static Resource dump(EObject objs) throws IOException { // ResourceSet rs = new ResourceSetImpl(); // rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put( // Resource.Factory.Registry.DEFAULT_EXTENSION, // new XMIResourceFactoryImpl()); // Resource resource = rs.createResource(URI // .createFileURI("c:\\temp\\test.xml")); XMLResource resource = new XMLResourceImpl(URI .createFileURI( " c:\\temp\\test.xml " )); resource.setEncoding( " GBK " ); for (EObject obj : objs) resource.getContents().add(obj); // 目前版本不加入resource验证会报singling异常 resource.save(System.out, null ); return resource; } }