首先我们理解这个构架的思路:
对于GMF是EMF+GEF.
GEF是典型的模型配置开发工具,但由于对底层数据模型,没有任何限制,从而在进行模型的数据的保存等操作时,都需要自己编写大量的代码。而EMF则提供了以上的缺陷。他从一个ecore的模型,提供了代码的相关代码的自动生成。也就是GMF.
而通过GEF的界面修改编写之后,会产生模型文件,而这个编写的模型文件怎么存在?这是一个关键点。要是找到这一点,那么再利用teneo的hibernate读取模型信息自动加载进数据库。那就是顺理成章了。
所以现在的关键点是编写好的模型文件GMF或者更准确的说是EMF是怎么为我们保存的。
幸运的是在Eclipse Modeling Framework2.0中15章,我们找到了这个持久化的相关信息。
在EMF对象是通过Resource接口被持久化的,方法是将它们添加到资源的内容列表,然后调用其save()方法。
我们不得不问
XML串行化被写入到什么位置,或者从什么位置读取他们?以及最初是从什么地方获取资源的?
URI
方案:例如platform:
特定于方案的部分:包含一个authority(//分隔一般指定网络环境的一个主机)、一个设备(前有/)和任意数量的段(前有/)。例如: URI: file:/c:/dir1/dir2/myfile.xml
可选片段:
URIConverter
URI转换器维护一组可由客户指定的URI到URI的映射。
使用EMF生成模型代码时,通常Eclipse会有一个缺省的保存格式。
在保存模型时,EMF会把根据模型生成一个EMF的Resource,然后用这个Resource来进行保存与加载。
在EMF中通常使用的Resource类型有:XML和XMI。在使用genmodel生成代码之前,我们可以设置要使用的Resource类型:
- None
- Basic
- XML
- XMI
- 如果选择None,则没有Resource类会被生成,可以看util包下的类;
- 如果选择的是一个Basic的类型,则会生成一个直接继承ResourceImpl的类;
- 如果选择的是XML类型,则会生成一个继承XMLResourceImpl的类;
- 模型的加载与保存就是在Resource类的doSave()和doLoad()方法中完成的。在继承之前,先介绍一些简单的修改方法。
注意在模型保存的时候,当然这是GEF中的,要在diagram中的
doSave方法中。当然还有doSave方法中。
那么此时,如果能得到模型的信息,那么则可以进行数据库的保存了。。哈哈。。爽!
@Override
public void doSave(IProgressMonitor progressMonitor) {
updateState(getEditorInput());
validateState(getEditorInput());
// performSave(false, progressMonitor);
ResourceSet resourceSet=new ResourceSetImpl();
URI uri=URI.createURI("file:/c:/data/out.ep2");
Resource resource=resourceSet.createResource(uri);
Topic ee=MindmapFactory.eINSTANCE.createTopic();
ee.setName("sunquan");
resource.getContents().add(ee);
try
{
resource.save(null);
System.out.println("saved");
}catch (Exception e) {
System.out.println("failed to write "+uri);
}
}
<?xml version="1.0" encoding="ASCII"?>
<mindmap:Topic xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:mindmap="http://www.example.org/mindmap"/>
<?xml version="1.0" encoding="ASCII"?>
<mindmap:Topic xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:mindmap="http://www.example.org/mindmap" name="sunquan"/>
这是我们在out.ep2的文件信息。
当然在上面我们所存的对象,仍然是手动创建的,而不是根据模型直接来的。寻找这个模型究竟是怎么来的。
我们突然从GEF中得到,是否可以监听模型的变化,然后在模型变化的时,也就是监听器触发时进行对象保存。
如在创建topic对象代码里:
protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
IAdaptable info) throws ExecutionException {
//看,这里响应创建命令,创建了一个Topic,那么,我们很容易得到的topic,也
//很容易进行数据库数据的插入。
Topic newElement = MindmapFactory.eINSTANCE.createTopic();
SessionFactory sessionFactory=hiberanteTest01.getSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(newElement);
session.getTransaction().commit();
session.close();
Map owner = (Map) getElementToEdit();
owner.getRootTopics().add(newElement);
doConfigure(newElement, monitor, info);
((CreateElementRequest) getRequest()).setNewElement(newElement);
return CommandResult.newOKCommandResult(newElement);
}
但在上面发现,这只是加入了一个topic,而对于模型的名称,还没有进行修改。
所以我们进一步发现 在GEF中,真正对于模型的修改都是在
set
方法中,进行的。那么,我们的数据添加等,是不是也可以在set中进行。
那现在,我们想在模型最终修改的时候进行数据添加。
那我们现在就需要找到设置的代码。
public void setName(String newName) {
String oldName = name;
name = newName;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, MindmapPackage.TOPIC__NAME, oldName, name));
}
这是通知了一个监听器,但响应这个监听器的代码在哪里呢?
这个监听的代码在这里。
public void setName(String newName) {
String oldName = name;
name = newName;
// if(newName!=null&&!newName.equals("")){
// SessionFactory sessionFactory=hiberanteTest01.getSessionFactory();
// Session session=sessionFactory.openSession();
// session.beginTransaction();
// this.name=newName;
// session.update((Topic)this);
// session.getTransaction().commit();
// session.close();
// System.out.println(newName);
// }
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, MindmapPackage.TOPIC__NAME, oldName, name));
}
对于mindmap这个应用,因为有外键的关系且不为空,所以在运行的时候要把无关的表删除之后,再操作,屏蔽掉主外键的联系。
以上是初始表。
注意org.eclipse.emf.teneo.hibernate的版本信息。。