服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

emf编程使用

       看到eclipse3.2里面的gmf, 觉得比较有趣,底层还是用到了emf. 花了两天时间仔细研究了以下emf,的确是个好东西.

emf根据ecore建模(可以和schema的xsd相互转换)生成强类型的emf代码. 这个强类型更强的地方是可以取得meta信息,从而可以用于校验和界面辅助信息的生成.类似于动态bean,属性也可以根据名称动态取得.

以前考虑过用xsd描述界面, 但是数据载体只能是xml, 即使利用apache的schema编译工具生成强类型的类,后台代码也是xml. 不利于持久化. emf在代码生成引擎比较智能,可以标记出用户代码和自动生成代码.不会有生成覆盖问题.

这里做个简单示例:
1. ecore:
可以新建ecore, 建立好以后用gmf可视化编辑(eclipse3.2rc2)
emf编程使用(图一)


2. 生成model:
点击my.ecore文件,菜单:file->new->other->eclipse modeling framework->emf model
3. 打开生成的my.genmodel, 选择树顶点的:generate model code
生成的代码里面会有一个编译错误. 是中文编程的问题, 中文没有大小写(先天不足啊),结果性别这个成员变量和性别类名混淆,出错.在错误代码前面加上包全名即可.
4. 利用生成的代码构建一个家庭,输出xml并且校验之:

emf编程使用(图二) import  java.io.ioexception;
emf编程使用(图二)
import  java.util.iterator;
emf编程使用(图二)
emf编程使用(图二)
import  org.eclipse.emf.common.util.diagnostic;
emf编程使用(图二)
import  org.eclipse.emf.common.util.uri;
emf编程使用(图二)
import  org.eclipse.emf.ecore.eobject;
emf编程使用(图二)
import  org.eclipse.emf.ecore.resource.resource;
emf编程使用(图二)
import  org.eclipse.emf.ecore.util.diagnostician;
emf编程使用(图二)
import  org.eclipse.emf.ecore.xmi.xmlresource;
emf编程使用(图二)
import  org.eclipse.emf.ecore.xmi.impl.xmlresourceimpl;
emf编程使用(图二)
import  org.steeven.family.familyfactory;
emf编程使用(图二)
import  org.steeven.family.人物;
emf编程使用(图二)
import  org.steeven.family.家庭;
emf编程使用(图二)
import  org.steeven.family.性别;
emf编程使用(图二)
emf编程使用(图三)emf编程使用(图四)
public   class  testmy  {
emf编程使用(图六)
emf编程使用(图七)emf编程使用(图八)    
public   static   void  main(string[] args)  throws  ioexception  {
emf编程使用(图六)        testfamily();
emf编程使用(图九)    }

emf编程使用(图六)
emf编程使用(图七) emf编程使用(图八)    
private   static   void  testfamily()  throws  ioexception  {
emf编程使用(图六)        家庭 family 
=  familyfactory.einstance.create家庭();
emf编程使用(图六)        family.settitle(
" steeven家 " );
emf编程使用(图六)        family.set老公(familyfactory.einstance.create人物());
emf编程使用(图六)        family.get老公().set姓名(
" steeven " );
emf编程使用(图六)        family.set老婆(familyfactory.einstance.create人物());
emf编程使用(图六)        family.get老婆().set姓名(
" stella " );
emf编程使用(图六)        family.get老婆().set性别(性别.女_literal);
emf编程使用(图六)        人物 sophie 
=  familyfactory.einstance.create人物();
emf编程使用(图六)        sophie.set姓名(
" sophie " );
emf编程使用(图六)        sophie.set性别(性别.女_literal);
emf编程使用(图六)        family.get兔崽子().add(sophie);
emf编程使用(图六)        dump(family);
emf编程使用(图六)        validate(family);
emf编程使用(图九)    }

emf编程使用(图六)
emf编程使用(图七) emf编程使用(图八)    
private   static   void  validate(eobject family)  {
emf编程使用(图六)        diagnostic diagnostic 
=  diagnostician.instance.validate(family);
emf编程使用(图六)        system.out.println(diagnostic);
emf编程使用(图七)emf编程使用(图八)        
for  (iterator it  =  diagnostic.getchildren().iterator(); it.hasnext();)  {
emf编程使用(图六)            diagnostic diag 
=  (diagnostic) it.next();
emf编程使用(图六)            system.out.println(diag.getmessage());
emf编程使用(图九)        }

emf编程使用(图九)    }

emf编程使用(图六)
emf编程使用(图七) emf编程使用(图八)    
private   static  resource dump(eobjectemf编程使用(图五) objs)  throws  ioexception  {
emf编程使用(图六)        
//  resourceset rs = new resourcesetimpl();
emf编程使用(图六)        
//  rs.getresourcefactoryregistry().getextensiontofactorymap().put(
emf编程使用(图六)        
//  resource.factory.registry.default_extension,
emf编程使用(图六)        
//  new xmiresourcefactoryimpl());
emf编程使用(图六)        
//  resource resource = rs.createresource(uri
emf编程使用(图六)        
//  .createfileuri("c://temp//test.xml"));
emf编程使用(图六)
        xmlresource resource  =   new  xmlresourceimpl(uri
emf编程使用(图六)                .createfileuri(
" c://temp//test.xml " ));
emf编程使用(图六)        resource.setencoding(
" gbk " );
emf编程使用(图六)        
for  (eobject obj : objs)
emf编程使用(图六)            resource.getcontents().add(obj); 
//  目前版本不加入resource验证会报singling异常
emf编程使用(图六)
        resource.save(system.out,  null );
emf编程使用(图六)        
return  resource;
emf编程使用(图九)    }

emf编程使用(图十)}

emf编程使用(图二)

运行结果如下:

<? xml version="1.0" encoding="gbk" ?>
emf编程使用(图二)
< family: 家庭 xmlns:family ="http://org.steeven/family"  title ="steeven家"  老公 ="/"  老婆 ="/"  兔崽子 ="/" />
emf编程使用(图二)diagnostic error 
emf编程使用(图二)the feature '老公' of 'org.steeven.family.impl.家庭impl@f6a746{file:/c:/temp/test.xml#/}' contains a dangling reference 'org.steeven.family.impl.人物impl@6eb38a{#//}'
emf编程使用(图二)the feature '老婆' of 'org.steeven.family.impl.家庭impl@f6a746{file:/c:/temp/test.xml#/}' contains a dangling reference 'org.steeven.family.impl.人物impl@1cd2e5f{#//}'
emf编程使用(图二)the feature '兔崽子' of 'org.steeven.family.impl.家庭impl@f6a746{file:/c:/temp/test.xml#/}' contains a dangling reference 'org.steeven.family.impl.人物impl@19f953d{#//}'
emf编程使用(图二)

可见输出的xml中没有包含人物的具体信息. 修改my.ecore中老公/老婆/兔崽子属性的containment属性为true,重新生成代码后运行结果如下:
emf编程使用(图二)<?xml version="1.0" encoding="gbk"?>
emf编程使用(图二)
<family:家庭 xmlns:family="http://org.steeven/family" title="steeven家">
emf编程使用(图二)  
<老公 姓名="steeven"/>
emf编程使用(图二)  
<老婆 性别="女" 姓名="stella"/>
emf编程使用(图二)  
<兔崽子 性别="女" 姓名="sophie"/>
emf编程使用(图二)
</family:家庭>
emf编程使用(图二)diagnostic ok


====================
emf单独运行成功~

这里ecore似乎不支持嵌套定义,不像schema那样一个complextype声明里面可以定义的很复杂, 也不像java的内部类. 似乎被作了简化, 更像关系数据库表之间的关系.

待求证问题:
1. emf的校验信息是否支持国际化.
2. emf数据的能否更方便的保存到数据.

emf的灵活和强大已经验证过, 用于c/s还是b/s应该都不是问题.

扫描关注微信公众号