emf开发_使用动态EMF建立元模型

2023-12-12 14:10

本文主要是介绍emf开发_使用动态EMF建立元模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

emf开发

Eclipse Modeling Framework(EMF)描述了数据模型,并允许从不同类型的数据模型工件(例如XML Schema,RationalRose®模型,Ecore模型或Java注释)轻松生成代码。 在代码生成过程中,EMF生成器会创建模型代码,其中包括类型安全接口和数据模型的实现类。 但是,在某些情况下,应用程序不需要这些类型安全的接口和实现类。 相反,需要可以在应用程序组件之间共享或由应用程序组件进一步处理的数据对象。

在这种情况下,动态EMF派上用场,因为它允许应用程序开发人员在运行时以编程方式制造内存中的核心模型,动态地创建其实例,并使用EMF反射API访问模型实例元素。

为什么选择动态EMF?

Dynamic EMF的主要价值在于,它允许您在运行时仅用几行代码即可构建基于Ecore的模型,然后出于各种目的创建和访问此动态模型的实例。 以这种方式构建核心模型有助于避免在不需要接口和实现类时生成它们。

这种创建模型和模型实例的方法在(但不限于)以下场景中特别有用:

  • 不需要类型安全的接口或实现类 -只需在应用程序组件之间共享简单的数据对象。 在这种情况下,使用EMF代码生成器生成模型代码对于应用程序来说将是开销,因为它将不必要地维护和部署整个生成的接口/类集。 使用动态EMF,可以动态地创建和实例化包含动态类的核心模型。 然后,这些动态类的实例可用于共享数据或由应用程序组件进行进一步处理。
  • 数据模型仅在运行时已知 —在这种情况下,由于在开发时不知道数据模型,因此通过EMF代码生成器创建静态模型不是一个好的选择。 可以在运行时构建和实例化的动态核心模型将更适合此类情况下的应用程序需求。

创建动态内存核心模型

我们首先以编程方式构建基于动态Ecore的模型,然后创建该模型的动态实例。 稍后,我们将看到如何读写模型实例中存在的元素的值。

创建基于Ecore的动态模型/元模型

我们将考虑一个书店模型来演示动态Ecore模型的创建。 为了清楚起见,我们使用统一建模语言(UML)表示模型。

图1. BookStore模型
书店模型

我们首先创建一组核心模型元素,包括一个EcoreFactory实例,一个EcorePackage实例,两个EClass实例和一个EPackage实例。 参见清单1。

清单1.创建核心模型元素
/*
* Instantiate EcoreFactory
*/
EcoreFactory theCoreFactory = EcoreFactory.eINSTANCE;/*
* Create EClass instance to model BookStore class
*/
EClass bookStoreEClass = theCoreFactory.createEClass();
bookStoreEClass.setName("BookStore");/*
* Create EClass instance to model Book class
*/
EClass bookEClass = theCoreFactory.createEClass();
bookEClass.setName("Book");/*
* Instantiate EPackage and provide unique URI
* to identify this package
*/
EPackage bookStoreEPackage = theCoreFactory.createEPackage();
bookStoreEPackage.setName("BookStorePackage");
bookStoreEPackage.setNsPrefix("bookStore");
bookStoreEPackage.setNsURI("http:///com.ibm.dynamic.example.bookstore.ecore");

所述EcoreFactory提供方法来创建像模型元素EClassEAttributeEPackage等。使用的实例EcoreFactory ,我们创建了两个EClass实例:一个用于表示BookStore类和其它来表示Book类(如在指定的BookStore模型) 。 接下来,我们创建一个EPackage ,最终将在其中放置BookStoreBook类。 然后,我们定义bookStoreEPackage的名称和nsPrefix属性。 由于包的名称不必是唯一的,因此应向bookStoreEPackage提供URI以唯一标识它。 这是通过使用setNsURI()方法设置nsURI属性的值来完成的。

现在,我们为动态类创建BookStore数据模型指定的属性。 要为每个属性设置模型化的数据类型,我们实例化EcorePackage ,其中包含用于表示每种数据类型的元对象的访问器。 参见清单2。

清单2.创建动态类的属性
/*
* Instantiate EcorePackage
*/
EcorePackage theCorePackage = EcorePackage.eINSTANCE;/*
* Create attributes for BookStore class as specified in the model
*/
EAttribute bookStoreOwner = theCoreFactory.createEAttribute();
bookStoreOwner.setName("owner");
bookStoreOwner.setEType(theCorePackage.getEString());
EAttribute bookStoreLocation = theCoreFactory.createEAttribute();
bookStoreLocation.setName("location");
bookStoreLocation.setEType(theCorePackage.getEString());
EReference bookStore_Books = theCoreFactory.createEReference();
bookStore_Books.setName("books");
bookStore_Books.setEType(bookEClass);
bookStore_Books.setUpperBound(EStructuralFeature.UNBOUNDED_MULTIPLICITY);
bookStore_Books.setContainment(true);/*
* Create attributes for Book class as defined in the model
*/
EAttribute bookName = theCoreFactory.createEAttribute();
bookName.setName("name");
bookName.setEType(theCorePackage.getEString());
EAttribute bookISBN = theCoreFactory.createEAttribute();
bookISBN.setName("isbn");
bookISBN.setEType(theCorePackage.getEInt());

接下来,我们需要将每个类的属性添加到相应类的eStructuralFeatures列表中。 最后,我们将两个类都放入动态包bookStoreEPackage 。 这样就完成了给定BookStore模型的元模型的创建。

清单3.将属性与各自的类相关联并将类放在动态包中
/*
* Add owner, location and books attributes/references
* to BookStore class
*/
bookStoreEClass.getEStructuralFeatures().add(bookStoreOwner);
bookStoreEClass.getEStructuralFeatures().add(bookStoreLocation);
bookStoreEClass.getEStructuralFeatures().add(bookStore_Books);/*
* Add name and isbn attributes to Book class
*/
bookEClass.getEStructuralFeatures().add(bookName);
bookEClass.getEStructuralFeatures().add(bookISBN);/*
* Place BookStore and Book classes in bookStoreEPackage
*/
bookStoreEPackage.getEClassifiers().add(bookStoreEClass);
bookStoreEPackage.getEClassifiers().add(bookEClass);

创建动态模型实例

创建了内存中的Ecore模型后,我们可以创建模型中存在的动态类的实例。 我们首先通过在bookStoreEPackage上调用getEFactoryInstance()方法来获得一个EFactory实例。

清单4.创建动态实例
/*
* Obtain EFactory instance from BookStoreEPackage 
*/
EFactory bookFactoryInstance = bookStoreEPackage.getEFactoryInstance();/*
* Create dynamic instance of BookStoreEClass and BookEClass
*/
EObject bookObject = bookFactoryInstance.create(bookEClass);
EObject bookStoreObject = bookFactoryInstance.create(bookStoreEClass);

如果该模型的实现是由EMF代码生成器生成的,它将为模型的包和工厂提供实现类。 正在初始化的生成包(通过其构造函数)注册生成的工厂,并实例化对生成的工厂类的eFactoryInstance引用。 因此,在生成的包上调用getEFactoryInstance()方法将返回相应的生成的工厂。 由于我们的动态核心模型中没有任何生成的工厂,也没有任何类型的生成的类,因此在bookStoreEPackage上调用getEFactoryInstance()方法将返回动态工厂EFactoryImpl的实例。

EFactoryImpl定义了create()操作,该操作创建并返回指定为参数的模型类的新实例。 对于生成的模型代码,此方法被生成的工厂覆盖,以创建和返回相应的生成的模型类的实例。 在动态元模型,因为没有生成的工厂/模型实现类,调用create()的方法EFactory实例将返回的实例EObjectImpl

读写动态模型

EObjectImpl类包含所有反射API的实现,可用于访问我们的动态类的属性,从而使您能够读写模型,如下所示。

清单5.获取/设置模型实例元素的值
/*
* Set the values of bookStoreObject attributes
*/
bookStoreObject.eSet(bookStoreOwner, "David Brown");
bookStoreObject.eSet(bookStoreLocation, "Street#12, Top Town, NY");
((List) bookStoreObject.eGet(bookStore_Books)).add(bookObject);/*
* Set the values of bookObject attributes
*/
bookObject.eSet(bookName, "Harry Potter and the Deathly Hallows");
bookObject.eSet(bookISBN, 157221);/*
* Read/Get the values of bookStoreObject attributes
*/
String strOwner =(String)bookStoreObject.eGet(bookStoreOwner);
String strLocation =(String)bookStoreObject.eGet(bookStoreLocation);/*
* Read/Get the values of bookObject attributes
*/
String strName =(String)bookObject.eGet(bookName);
Object iISBN = bookObject.eGet(bookISBN);

同样,可以在需要时在模型类上调用EObjectImpl类中实现的其他反射API( eIsSet()eUnSet() )。

序列化动态模型

可以使用EMF Persistence框架的四个基本接口对动态模型进行序列化: ResourceResourceSetResource.FactoryURIConverter 。 序列化的过程将取决于我们是否要在要反序列化的同一程序中序列化模型,或者是否希望在与加载或反序列化模型的程序无关的其他程序中序列化模型。

如果要在同一程序中完成核心模型的序列化和反序列化,请执行以下操作; 如果不是,请转到清单7。要初始化序列化过程,我们首先注册XML资源工厂以处理具有任何扩展名的文件,如清单6所示。接下来,我们通过调用createResource()在资源集中创建一个空资源。 createResource()方法在ResourceSet实例上,并将ResourceSet的实际位置作为URI传递。 我们将EObjectbookStoreEObject )添加到该资源的内容列表中,并使用save()方法将资源复制到其持久性存储中。 (如果需要,资源集可以使用URIConverter来定位资源或将输入URI规范化为资源的实际URI。)

清单6.序列化动态模型实例
ResourceSet resourceSet = new ResourceSetImpl();
/*
* Register XML Factory implementation using DEFAULT_EXTENSION
*/
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new  XMLResourceFactoryImpl());/*
* Create empty resource with the given URI
*/
Resource resource = resourceSet.createResource(URI.createURI("./bookStore.xml"));/*
* Add bookStoreObject to contents list of the resource 
*/
resource.getContents().add(bookStoreObject);try{/** Save the resource*/resource.save(null);}catch (IOException e) {e.printStackTrace();}

动态模型的最终序列化实例如图2所示。

图2.动态模式的序列化实例
动态模式的序列化实例

如果要在不同的独立程序中进行核心模型的序列化和反序列化,请使用以下序列化过程; 如果不是,请返回清单6。在加载动态模型时,我们需要访问动态包bookStoreEPackage 。 如果要将模型装入序列化的同一程序中,则可以轻松完成此操作(请参阅下一节)。 但是,如果要在与序列化模型不同的程序中加载模型,则需要在序列化模型实例之前序列化动态Ecore模型,以便能够访问bookStoreEPackage

清单7.序列化元模型
ResourceSet metaResourceSet = new ResourceSetImpl();/*
* Register XML Factory implementation to handle .ecore files
*/
metaResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", new  XMLResourceFactoryImpl());/*
* Create empty resource with the given URI
*/
Resource metaResource = \
metaResourceSet.createResource(URI.createURI("./bookStore.ecore"));/*
* Add bookStoreEPackage to contents list of the resource 
*/
metaResource.getContents().add(bookStoreEPackage);try {/** Save the resource*/metaResource.save(null);} catch (IOException e) {e.printStackTrace();}

我们首先注册一个XML资源工厂实现来处理带有Ecore扩展名的文件,因为核心模型将使用该扩展名进行序列化。 接下来,我们创建一个空资源,并将动态包bookStoreEPackage添加到此新创建资源的内容列表中。 最后,我们保存此资源。

生成的序列化动态核心模型或元模型如图3所示。

图3.序列化的动态核心模型
序列化动态核心模型

现在我们序列化模型实例文档:bookStore.xml。 唯一的区别是这次,实例文档使用附加属性xsi:schemaLocation进行了序列化。 加载程序将使用此属性来查找持久资源bookStore.ecore ,其中包含加载模型实例文档所需的序列化EPackage

清单8.使用xsi:schemaLocation属性序列化模型实例文档
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new  XMLResourceFactoryImpl());Resource resource = resourceSet.createResource(URI.createURI("./bookStore.xml"));
resource.getContents().add(bookStoreObject);/*
* Save the resource using OPTION_SCHEMA_LOCATION save option toproduce 
* xsi:schemaLocation attribute in the document
*/
Map options = new HashMap();
options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
try{resource.save(options);}catch (IOException e) {e.printStackTrace();}

序列化的模型实例文档bookstore.xml将带有xsi:schemaLocation属性,如下所示。

图4.具有xsi:SchemaLocation属性的序列化模型实例
具有xsi:SchemaLocation属性的序列化模型实例

反序列化/加载动态模型

现在,我们将看到如何加载刚刚序列化的动态模型实例文档。

如果核心模型的序列化和反序列化是在同一程序中完成的,则使用此反序列化过程。 在序列化过程中,我们首先在资源工厂实现中注册XML,以处理具有任何扩展名的文件。 之后,我们使用序列化模型时给定的相同名称空间URI,将动态bookStoreEPackage添加到包注册表中。 (此URI在我们生成的序列化模型实例文档中显示为xmlns:book=http:///com.ibm.dynamic.example.bookstore.ecore 。)

清单9.加载模型实例文档
ResourceSet load_resourceSet = new ResourceSetImpl();/*
* Register XML Factory implementation using DEFAULT_EXTENSION
*/
load_resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new XMLResourceFactoryImpl());/*
* Add bookStoreEPackage to package registry
*/
load_resourceSet.getPackageRegistry().put("http:///com.ibm.dynamic.example.bookstore.ecore",bookStoreEPackage);/*
* Load the resource using the URI
*/
Resource load_resource = load_resourceSet.getResource(URI.createURI("./bookStore.xml"),true);/*
* Read back the serialized instances of dynamic classes stored in the 
* resource
*/
EObject readBookStoreObject = (EObject)load_resource.getContents().get(0);
EObject readBookObject = (EObject)((EList)(readBookStoreObject.eGet(bookStore_Books))).get(0);System.out.println("Owner: " + readBookStoreObject.eGet(bookStoreOwner)+ "\nLocation: " + readBookStoreObject.eGet(bookStoreLocation)+ "\nBook:\n name: " + readBookObject.eGet(bookName) + "\t isbn: " + readBookObject.eGet(bookISBN));

在我们的程序包在程序包注册表中注册后,我们通过在资源集实例上调用getResource()方法来加载资源。 这将使用我们作为参数传递给getResource()方法的URI加载模型实例文档。 最后,我们使用反射API访问文档中的序列化实例,如上所示。

如果核心模型的序列化和反序列化是在不同的独立程序中完成的,请遵循此过程。 在这里,加载实例文档的过程保持不变,除了我们不必将动态bookStoreEPackage添加到ResourceSet的包注册表中。 这是因为当我们加载实例文档bookStore.xml时,加载程序会在实例文档的xsi:schemaLocation属性中找到命名空间URI,以打包URI映射。 使用此映射,加载程序将自动加载包含动态bookStoreEPackage的序列化bookStore.ecore模型。 装入此动态包之后,可以使用反射EMF的API以通常的方式访问序列化的实例,如清单9所示。

局限性

与通过EMF生成器生成的模型相比,使用动态EMF构建的模型要慢一些,并占用更多空间。 这是因为动态模型依靠EObjectImpl类提供的反射API的动态实现来获取和设置实例的动态功能。 例如,动态模型将使用较慢的eGet(EstructuralFeature myFeature)方法,而不是所生成的核心模型使用较快的(生成的) getMyFeature()方法。 此外,动态设置在动态模型实例中需要额外的空间,如果使用EMF代码生成器生成模型代码则不需要。

结论

您学习了如何使用动态EMF构建基于Ecore的模型,该模型可以在没有相应Java实现类的情况下即时创建和实例化。 在通过EMF代码生成器生成部分应用程序模型代码,而使用Dynamic EMF构建其余模型代码的情况下,这种构建模型的方法的使用变得特别有趣。 在这种情况和类似情况下,如果有效利用动态EMF,则可以使应用程序以反射方式共享数据大有帮助。 同时,它可以减少生成的实现代码,否则在模型发展时将需要对其进行维护。


翻译自: https://www.ibm.com/developerworks/opensource/library/os-eclipse-dynamicemf/index.html

emf开发

这篇关于emf开发_使用动态EMF建立元模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/484908

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G