`

EMF的JMerger使用

阅读更多

在生成java代码的中经常会遇到Java文件的合并问题,EMF的org.eclipse.emf.codegen插件提供了Java文件合并的工具类,用户只需要配置一定的规则就可以解决java文件的合并问题。

 

Jmerge-Name.jpg

EMF提供了简介的API调用:

 

public String mergeContent(String sourceContent,String targetContent)
{
//用户配置的合并规则
String jmergeRuleURI= URI.createPlatformPluginURI(
				"org.eclipse.emf.codegen.ecore/templates/emf-merge.xml", false).toString(); //$NON-NLS-1$

JControlModel model = new JControlModel();
model.initialize(new ASTFacadeHelper(), jmergeRuleURI);
JMerger jMerger = new JMerger(model);
jMerger.setSourceCompilationUnit(jMerger.createCompilationUnitForContents(sourceContent));
jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForContents(targetContent);
//执行合并规则
jMerger.merge();
return jMerger.getTargetCompilationUnit().getContents();
}				

 从上面代码可以看出合并规则是重点,我们以"org.eclipse.emf.codegen.ecore"插件中本身提供的emf-merge.xml来简要说明规则。

首先需要说明的是,我们对Java中的元素用节点(Node)表示,例如Field、Method都是java可编译单元的节点。对于java文件合并,无非三种情况:

1、如果Java Source中存在该节点,而且Java Target中也同样存在该节点,如何合并

2、如果Java Source中存在该节点,但是Java Target中不存在该节点,如何处理

3、如果Java Source中不存在该节点,但是Java Target中存在该节点,如何处理

在合并规则的xml文件中对这三种情况都有相应的配置。

 

其次在合并规则中有个重要的标记概念(markup),个人理解就是对节点的划分,比如一部分节点是自动生成的,这部分就属于“gen”的标记范围。这样在运用合并规则的时候,就可以对某一个范围进行操作。

 

 

下面首先看一下如何定义标记,

  <merge:dictionaryPattern

    name="generatedUnmodifiableMembers" 

    select="Member/getComment" 

    match="@\s*(gen)erated\s*(This field/method[^(?:\n\r?|\r\n?)]*)*(?:\n\r?|\r\n?)"/>

name属性仅仅在没有捕获的内容的时候作为标记名,例如 match="@\s*model" 可以匹配这个正则表达式,但是正则表达式中没有捕获的内容,那么将会用该名字作为标记,select属性中的内容分为两部分,并由‘/’分割。前面的部分表示节点的具体类型,示例中为Member,则表示节点的实际类型为org.eclipse.emf.codegen.merge.java.facade.JMember(可以查看该包下的JNode及子类,把Java可编译单元解析成具体的语法树模型),后面的getComment表示该实际类型的方法名。match属性为正则表达式。这个标记就表示如果JMember类型的comment可以匹配match所表示的正则表达式,那么这个JMember就属性'gen'标记。其中‘gen’就是正则表达式中捕获的字符串。

如果我的java代码如下:

/**

* Returns the value of the '<em><b>Title</b></em>' attribute.

* @generated

*/

 

String getTitle();

那么该节点会放在‘gen’标记中。

其他定义标签示例:

  <merge:dictionaryPattern

    name="modelMembers" 

    select="Member/getComment" 

 

    match="@\s*(model)"/>

 

 

EMF生成的Java代码的模型标记

 

如何定义合并规则:

1、如果Java Source中存在该节点,而且Java Target中也同样存在该节点,如何合并

使用pull元素来定义规则:

  <merge:pull 

    sourceMarkup="^gen$"

    sourceGet="Member/getComment"

    targetMarkup="^gen$"

    targetPut="Member/setComment"/>

sourceMarkup表示节点所属的标记,sourceGet也是有两部分组成,一部分表示节点的类型,另一部分表示获得的方法。该合并规则表示,如果target中的JMember类型属于'gen'标签,而且对应的source JMember类型也属于'gen'标签,那么会把source的comment设置到target的comment中。

如果想保留target中的部分java注释的话需要使用sourceTransfer属性,例如sourceTransfer="(\s*&lt;!--\s*begin-user-doc.*?end-user-doc\s*-->\s*)(?:\n\r?|\r\n?)",表示将会保留target中“// begin-user-code” 和“ // end-user-code” 包围住的所有的字符。

2、如果Java Source中存在该节点,但是Java Target中不存在该节点,如何处理

使用push元素定义规则:

 <merge:push targetParentMarkup="^gen$" select="Annotation"/>

表示如果Annotation节点的父属于'gen'标记,则会在target中添加该注解。

事实上在默认情况下如果没有声明所属的标记,默认markup为ture的,个人理解这个节点可以实现那些节点可以不用合并到target中,即仅仅在target父类型标记不为'gen'标记,则不会合并到target中。

 

3、如果Java Source中不存在该节点,但是Java Target中存在该节点,如何处理

使用sweep元素来定义规则:

  <merge:sweep markup="^gen$" select="Member"/>

表示如果该节点类型为JMember,而且属于'gen'标记,则会删除该节点。

实际上对于这种情况,如果JMerger提供了三种策略,删除节点,注释节点、重命名节点。默认为删除策略,通过action属性设置

 

如何根据source排序

如果想根据source中的顺序对target进行排序,需要定义排序规则:

  <merge:sort markup="^ordered$" select="Field"/>

如果source中field为f2/f1/f3.而且target中存在相应的Field,那么在合并后的输出Field为source的顺序,即f2/f1/f3。

 

在合并规则的xml根节点上可以定义不执行合并的Pattern

<merge:options 

  indent="  "  

  braceStyle="matching"  

  redirect="Gen"

  block="\s*@\s*generated\s*NOT\s*(?:\n\r?|\r\n?)"

  noImport="\s*//\s*import\s+([\w.*]*)\s*;\s*(?:\n\r?|\r\n?)"

  xmlns:merge="http://www.eclipse.org/org/eclipse/emf/codegen/jmerge/Options">

 

block属性就是不执行合并的模式,当用户的comment能匹配这种模式的时候,pull规则不会应用(即失效)。如果Type的comment匹配这种模式,这这个类型就不会执行合并操作。

 

参考:http://www.blogjava.net/JetGeng/archive/2006/05/01/44261.html

           http://www.blogjava.net/JetGeng/archive/2006/05/02/44342.html

分享到:
评论

相关推荐

    Eclipse开发使用GEF和EMF(IBM 红皮书)中英文对照版

    《Eclipse开发使用GEF和EMF》是IBM红皮书系列中的一部经典著作,主要探讨了如何在Eclipse环境中利用GEF(图形编辑框架)和EMF( Eclipse模型框架)进行图形化应用程序的开发。这两项技术是Eclipse平台上的核心组件,...

    emf文件格式详解

    通过阅读这份文档,读者可以了解到如何创建、编辑和解析EMF文件,以及EMF在应用程序中的使用方式,比如打印、图像处理和图形显示。 **emf.hlp**:这是一个帮助文件,通常用于提供快速查询和参考。在这个文件中,...

    微软emf文件格式详解

    EMF(Enhanced MetaFile)是一种在Windows操作系统中广泛使用的高级元文件格式。它作为WMF(Windows Metafile)格式的32位增强版,旨在解决WMF在印刷行业中的一些限制。EMF格式的一个显著特点是其设备独立性,这意味...

    EMF文件提取文本,预览,打印

    EMF(Enhanced Metafile)文件是Windows操作系统中使用的一种矢量图形和图元文件格式。这种文件类型被广泛用于存储图形、图像和打印数据,因为它支持复杂的图形操作,如曲线绘制、渐变填充和透明效果。EMF文件是GDI+...

    EMF读取XML

    - 使用EMF,首先需要创建一个Ecore模型,这是EMF的数据模型定义,包含了类、属性和关系等元数据。 - 可以通过Eclipse的EMF插件自动生成Ecore模型,或者手动编写.xmi文件来定义模型。 - 一旦模型创建完成,EMF会...

    SVG转EMF的示例代码

    本示例代码是关于如何使用Java将SVG转换为EMF,这在需要在Windows系统中处理矢量图形时非常有用,因为EMF是Windows系统广泛支持的格式。 SVG是一种基于XML的开放标准,用于描述2D图形。它支持复杂的形状、路径、...

    将EMF图片格式转换成PNG

    总的来说,将EMF转换为PNG的过程涉及到了Java编程、图像处理库的使用以及文件格式的转换。通过`freehep`库,我们可以方便地在Java环境中实现这种转换,为跨平台的应用提供了便利。在实际开发中,你还可以扩展这个...

    emf文件和wmf的转换

    解决方案文件"emf2wmf.sln"和项目文件"emf2wmf.vcproj"则表明这是一个使用Microsoft Visual Studio开发的C++项目,用于编译和运行转换代码。 在转换过程中,开发者需要考虑的关键点包括: 1. **记录解析**:EMF和...

    使用EMF开发基于模型的Eclipse插件

    ### 使用EMF开发基于模型的Eclipse插件 #### EMF简介 Eclipse Modeling Framework(EMF)是Eclipse项目下的一个重要的组成部分,它提供了一种基于Java的模型构建框架。EMF的主要特点在于它能够极大程度上简化基于...

    emf教程入门和插件

    本教程旨在帮助初学者理解EMF的基础概念,并通过实践掌握EMF插件的使用。 1. **EMF基础** EMF基于MDE(Model Driven Engineering)理念,允许开发者创建、编辑和管理模型。模型是业务逻辑的一种抽象表示,可以用来...

    emf eclipse

    3. "使用EMF Query查询EMF模型(2) - 编程入门网" 这部分可能深入介绍了EMF Query(EMF QL),这是一个用于查询和操作EMF模型的强大工具。通过EMF QL,开发者可以方便地检索、分析和修改模型数据。 总结来说,EMF ...

    eclipse emf&gef

    通过将GEF与EMF结合使用,可以轻松创建高度可定制的图形化编辑器,用于编辑由EMF生成的模型。 **3.3 GEF编辑器开发流程** 1. **定义模型**:首先使用EMF定义模型。 2. **创建视图**:使用GEF创建一个图形化的视图...

    EMF模型文件对比/比较(emf.compare)

    首先,从提供的标签“源码”和“工具”来看,我们可以推断这篇文章可能涉及了EMF.compare的源代码分析以及它是如何作为开发者工具来使用的。EMF.compare作为一个开源项目,其源代码对开发者来说是开放的,允许他们...

    EMF 自学笔记5

    ### EMF自学笔记知识点详述 #### 一、EMF框架概述 EMF(Eclipse Modeling Framework)是Eclipse项目中的一个子项目,它提供了一套用于构建模型驱动的开发工具和应用程序的框架。EMF的主要目标是简化元数据驱动应用...

    emf-runtime-2.7.2

    1. **元模型(Metamodel)定义**:EMF允许开发者使用Ecore语言定义元模型,这是对数据模型的一种抽象描述。 2. **代码生成**:基于元模型,EMF可以自动生成Java类和其他相关代码,这些代码可以直接在应用程序中使用...

    获取WMF、EMF图片中文字所用字体名称

    为了解决这个问题,我们需要有一种方法来识别并获取WMF和EMF图片中使用的特定字体。这正是"获取WMF、EMF图片中文字所用字体名称"这个程序的功能。这个代码能够解析WMF和EMF文件的元数据,提取出其中涉及的所有字体...

    java开发工具EMF插件

    本文将深入探讨EMF插件的核心功能、使用场景以及如何在Eclipse环境中集成和使用EMF。 一、EMF插件概述 EMF插件是基于Java的元数据框架,它允许开发人员创建、编辑和管理复杂的模型。这些模型可以用来表示业务逻辑、...

Global site tag (gtag.js) - Google Analytics