首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

淺析 Eclipse Modeling Framework (EMF) 核心與動態建模能力

     編輯:Java 相關知識

EMF(Eclipse Modeling Framework)是基於結構化模型的代碼生成與運行時框架,支援從 Ecore、UML、XML Schema、註解 Java 接口生成模型代碼,並提供反射 API、變更通知、跨文檔引用、驗證與持久化能力。本文解析核心概念並演示動態模型用法。

一、核心元模型:Ecore

  • Ecore 是 EMF 的類 MOF 核心元模型,對應 Essential MOF (EMOF);
  • 關鍵接口 EObject(相當 java.lang.Object),提供 eClass()、eGet/eSet、eContainer()、Notifier 變更監聽;
  • 支援模型合並、重新生成保留手寫代碼。

二、動態建模:無需生成代碼直接操作模型

適用於開發期模型未知、需解析任意 XML Schema 等場景。

1. 編程構建 Company 模型

EcoreFactory ef = EcoreFactory.eINSTANCE;
EcorePackage ep = EcorePackage.eINSTANCE;

// Company 類
EClass company = ef.createEClass(); company.setName("Company");
EAttribute cName = ef.createEAttribute(); cName.setName("name"); cName.setEType(ep.getEString());
company.getEStructuralFeatures().add(cName);

// Employee 類
EClass employee = ef.createEClass(); employee.setName("Employee");
EAttribute eName = ef.createEAttribute(); eName.setName("name"); eName.setEType(ep.getEString());
employee.getEStructuralFeatures().add(eName);

// Department 類
EClass dept = ef.createEClass(); dept.setName("Department");
EAttribute dNo = ef.createEAttribute(); dNo.setName("number"); dNo.setEType(ep.getEInt());
dept.getEStructuralFeatures().add(dNo);

// 關聯:Department → Employee* (containment)
EReference deptEmps = ef.createEReference();
deptEmps.setName("employees"); deptEmps.setEType(employee);
deptEmps.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
deptEmps.setContainment(true);
dept.getEStructuralFeatures().add(deptEmps);

// 關聯:Company → Department* (containment)
EReference compDepts = ef.createEReference();
compDepts.setName("department"); compDepts.setEType(dept);
compDepts.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
compDepts.setContainment(true);
company.getEStructuralFeatures().add(compDepts);

// Package
EPackage pkg = ef.createEPackage();
pkg.setName("company"); pkg.setNsPrefix("company"); pkg.setNsURI("https:///com.example.company.ecore");
pkg.getEClassifiers().addAll(Arrays.asList(employee, dept, company));

2. 反射 API 創建實例

EFactory factory = pkg.getEFactoryInstance();
EObject companyObj = factory.create(company);
companyObj.eSet(cName, "MyCompany");

EObject emp = factory.create(employee);
emp.eSet(eName, "John");

EObject dep = factory.create(dept);
dep.eSet(dNo, 123);
((List)dep.eGet(deptEmps)).add(emp);
((List)companyObj.eGet(compDepts)).add(dep);

3. 序列化 (XMI) 與反序列化

ResourceSet rs = new ResourceSetImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
Resource res = rs.createResource(URI.createFileURI("c:/temp/company.xmi"));
res.getContents().add(companyObj);
res.save(null);  // 生成 XMI 文件

// 反序列化
rs.getPackageRegistry().put(pkg.getNsURI(), pkg);
res.load(null);

三、從 XML Schema 動態生成 Ecore

XSDEcoreBuilder builder = new XSDEcoreBuilder();
ResourceSet rs = new ResourceSetImpl();
Collection pkgs = builder.generate(URI.createFileURI("c:/temp/ipo.xsd"));
// pkgs 已自動註冊到 rs,可直接載入對應 XML 實例
Map opts = new HashMap();
opts.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
Resource xmlRes = rs.createResource(URI.createFileURI("c:/temp/ipo.xml"));
xmlRes.load(opts);

EMF 2.1+ 還支援無 Schema 的 XML 載入(GenericXMLResourceFactoryImpl),並能自動解析 xsi:schemaLocation。

四、應用場景與生態

  • XSD (XML Schema Infoset Model)、SDO (Service Data Objects)、UML2、WTP 皆建於 EMF 之上;
  • 商業產品:IBM Rational/WebSphere、Omondo EclipseUML;
  • 提供標準化模型交換格式 (XMI),實現工具鏈互操作。

EMF 將「模型」提升為一等公民,賦予領域建模以代碼生成、運行時反射、持久化與驗證的完整工程化能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved