本文是一个简单的案例,讲解如果脱离eclipse的插件环境使用EMF建模后的生成代码。
EMF的建模过程使用的是eUML2, 该程序为eclipse插件, 支持在eclipse环境中构建,生成EMF模型文件。
eUML2 下载网址为 www.soyatec.com. Eclipse update 地址为
1 创建Empty EMF 项目
2 在新建对话框中选择EMF Class Diagram, 创建eUML2的建模图表文件。
3 模型例子如下,成个模型的入口为Company, Company有雇佣和解雇员工的权力。Employee继承自Person,提供有别于普通人定义的薪水属性。
要注意的地方是,每个类的属性中不要选中 Is an interface 选项,否则只会生成模型的定义接口,不会生成具体的实现类。(如下图)
4 在新建对话框中,选择EMF Model, 创建EMF 模型文件
填写文件的名字和存放地址,文件名后缀必须是genmodel
选择从Ecore model文件导入模型。
在使用eUML2构建模型图表后,会生成.ecore文件。其中保存的EMF模型的相关信息,按照下图导入该文件即可。
5 生成.genmodel文件后,打开该文件,右键单击,选择Generate Model Code,即会根据模型信息生成可供使用的java文件。
同样,在设计EMF 模型的editor中,在右键菜单中,同样会出现生成代码的选项。在本文中,只生成模型代码,因为并不使用其他跟eclipse开发环境相关的功能。(如editor等)
6 生成的代码如下图红框部分所示。Model部分是模型的定义接口部分;model.impl是模型的实现部分;model.util提供了一些工具类。
7 上图中file包中的EmplyManager类,进行相关持久化的工作。Observer提供了一个监听资源变化的观察者。
package
file;
import
java.io.IOException;
import
java.util.ArrayList;
import
java.util.Iterator;
import
java.util.List;
import
model.Company;
import
model.Employee;
import
model.ModelFactory;
import
model.ModelPackage;
import
org.eclipse.emf.common.notify.Adapter;
import
org.eclipse.emf.common.util.URI;
import
org.eclipse.emf.ecore.EPackage;
import
org.eclipse.emf.ecore.resource.Resource;
import
org.eclipse.emf.ecore.resource.ResourceSet;
import
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import
org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
public
class
EmployManager
...
{
String file = "MyBak.model";
private List<Company> companies;
public EmployManager() ...{
companies = load();
}
public List<Company> getCompany() ...{
return companies;
}
public Company getCompany(String name) ...{
for (int i = 0; i < companies.size(); i++) ...{
Company com = companies.get(i);
if (com.getName() != null && com.getName().equals(name)) ...{
return com;
}
}
return createCompany(name);
}
public void hireEmploy(String companyName, String name, int age) ...{
Company company = getCompany(companyName);
Employee employee = ModelFactory.eINSTANCE.createEmployee();
employee.setName(name);
employee.setAge(age);
company.hire(employee);
}
public List<Company> load() ...{
// 创建资源集合
ResourceSet resourceSet = new ResourceSetImpl();
// 注册处理数据持久化的工厂类,model为文件后缀名
Resource.Factory.Registry registry = resourceSet.getResourceFactoryRegistry();
registry.getExtensionToFactoryMap().put("model", new EcoreResourceFactoryImpl());
// 注册类所在包的名字空间
EPackage.Registry reg = resourceSet.getPackageRegistry();
reg.put(ModelPackage.eNS_URI, ModelPackage.eINSTANCE);
List<Company> c = new ArrayList<Company>();
try ...{
// 读取文件
URI uri = URI.createFileURI(file);
Resource resource = resourceSet.getResource(uri, true);
resource.load(null);
//直接读取对象信息
for (Iterator iterator = resource.getContents().iterator(); iterator.hasNext();) ...{
Company company = (Company) iterator.next();
c.add(company);
}
} catch (Exception e) ...{
}
return c;
}
public Company createCompany(String name) ...{
Company c = ModelFactory.eINSTANCE.createCompany();
c.setName(name);
companies.add(c);
return c;
}
public void save() ...{
// 创建资源集合
ResourceSet resourceSet = new ResourceSetImpl();
// 添加资源状态改变监听器
resourceSet.eAdapters().add(new Observer());
// 注册处理数据持久化的工厂类,model为文件后缀名
Resource.Factory.Registry registry = resourceSet.getResourceFactoryRegistry();
registry.getExtensionToFactoryMap().put("model", new EcoreResourceFactoryImpl());
// 注册类所在包的名字空间
EPackage.Registry reg = resourceSet.getPackageRegistry();
reg.put(ModelPackage.eNS_URI, ModelPackage.eINSTANCE);
// 读取文件
URI uri = URI.createFileURI(file);
// 获取该文件的资源信息
Resource resource = resourceSet.createResource(uri);
for (int i = 0; i < companies.size(); i++) ...{
Company company = companies.get(i);
resource.getContents().add(company);
}
try ...{
// 保存对象
resource.save(null);
} catch (IOException e) ...{
e.printStackTrace();
}
}
public static void main(String[] args) ...{
// Resource resource = new Loader().load("My.model");
// for (Iterator iterator = resource.getContents().iterator(); iterator
// .hasNext();) {
// Company company = (Company) iterator.next();
// System.out.println(company);
// }
EmployManager l = new EmployManager();
l.hireEmploy("talend", "Nicolas", 28);
l.hireEmploy("soyatec", "moneyice", 26);
l.hireEmploy("xcalia", "Tom", 30);
l.save();
List<Company> company = l.load();
for (Iterator<Company> iter = company.iterator(); iter.hasNext();) ...{
Company element = (Company) iter.next();
System.out.println(element.getName() + "'s employer : " + element.getEmployees());
}
}
}
package
file;
import
org.eclipse.emf.common.notify.Notification;
import
org.eclipse.emf.ecore.util.EContentAdapter;
public
class
Observer
extends
EContentAdapter
...
{
@Override
public void notifyChanged(Notification notification) ...{
int type = notification.getEventType();
if (type == Notification.ADD) ...{
// do something
}
if (type == Notification.SET) ...{
// do something
}
super.notifyChanged(notification);
}
}
保存的文件为名字为MyBak.model,内容如下:
<?
xml version="1.0" encoding="UTF-8"
?>
<
xmi:XMI
xmi:version
="2.0"
xmlns:xmi
="http://www.omg.org/XMI"
xmlns:model
="http://model"
>
<
model:Company
name
="talend"
>
<
employees
name
="Nicolas"
age
="28"
/>
<
employees
name
="Nicolas"
age
="28"
/>
</
model:Company
>
<
model:Company
name
="soyatec"
>
<
employees
name
="moneyice"
age
="26"
/>
<
employees
name
="moneyice"
age
="26"
/>
</
model:Company
>
<
model:Company
name
="xcalia"
>
<
employees
name
="Tom"
age
="30"
/>
<
employees
name
="Tom"
age
="30"
/>
</
model:Company
>
</
xmi:XMI
>
EmployManager可以以Application的形式运行,注意要引入以下3个jar文件。