`

代码生成技术学习之二 JMerger

阅读更多
代码自动生成,生成的代码许多时候需要修改,以满足我们的需求,而修改的代码我们希望重新生成代码的时候不被覆盖,那就需要一种Merge技术。JMerger和JET模板是在EMF代码生成中使用的关键技术。下面我们看一下一个使用JMerger的例子:
两个java文件:
HelloSrc.java

package hello;

public class Hello{
    
    public void say(){
        System.out.println("hello");
    }
    
    /**
     * @generated
     */
    public void sayHelloTo(String name){
        System.out.println("Hello," + name);
    }
    
    public void test(){
        
    }
}


HelloTarget.java
package hello;

public class Hello 
{
    
   public void say(){
       System.out.println("hello world");
   }
   /**
    * @generated
    */
   public void sayHelloTo(String name){
       System.out.println(name);
   }
}


我们使用JMerger来合并覆盖原先生成的的方法//@generated标记的方法,而我们
自己定义的方法和去掉@generated的的方法则不被覆盖。
我们需要增加某种机制来告诉 JMerge 有些方法已经被修改过了,因此这些方法不应该被重写。要实现这种功能,可以使用 <merge:dictionaryPattern> 元素。 merge:dictionaryPattern 允许您使用正则表达式来区分 Java 元素:
<?xml version="1.0" encoding="UTF-8"?>
<merge:options xmlns:merge="http://www.eclipse.org/org/eclipse/emf/codegen/jmerge/Options">
 <merge:dictionaryPattern
   name="generatedMember" 
   select="Member/getComment" 
   match=
        "s*@s*(gen)erateds*"/>
 
 <merge:pull 
   targetMarkup="^gen$"
   sourceGet="Method/getBody"
   targetPut="Method/setBody"/>
 
</merge:options>


dictionaryPattern 定义了一个正则表达式,它可以匹配注释中包含 " @generated " 的成员。 select 属性列出了要对这个成员的哪些部分与在 match 属性中给出的正则表达式进行比较。 dictionaryPattern 是由字符串 gen 定义的,它就是 match 属性值中圆括号中的内容。merge:pull 元素多了一个附加属性 targetMarkup 。这个属性可以匹配 dictionaryPattern ,它必须在应用合并规则之前对目标代码进行匹配。此处,我们正在检查的是目标代码,而不是源代码,因此用户可以定制这些代码。当用户删除注释中的 " @generated " 标签时, dictionaryPattern 就不会与目标代码匹配,因此就不会合并这个方法体
package hello;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.emf.codegen.merge.java.JControlModel;
import org.eclipse.emf.codegen.merge.java.JMerger;
import org.eclipse.emf.codegen.merge.java.facade.ast.ASTFacadeHelper;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;

public class JMergerTest
{
    public static void merge( File src, File target )
    {
        JControlModel model = new JControlModel();
        ASTFacadeHelper astFacadeHelper = new ASTFacadeHelper()
        {
            Map<String, String> options;
            @SuppressWarnings("unchecked")
            @Override
            public Map getJavaCoreOptions()
            {
                if( options == null )
                {
                    options = new HashMap<String, String>();
                    options.put( JavaCore.COMPILER_COMPLIANCE,
                                 JavaCore.VERSION_1_6 );
                    options.put( JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6 );
                    options.put( JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
                                 JavaCore.VERSION_1_6 );
                    options.put( JavaCore.COMPILER_PB_ASSERT_IDENTIFIER,
                                 JavaCore.ERROR );
                    options.put( JavaCore.COMPILER_PB_ENUM_IDENTIFIER,
                                 JavaCore.ERROR );
                    options.put( JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE,
                                 JavaCore.ENABLED );
                    options.put( JavaCore.COMPILER_DOC_COMMENT_SUPPORT,
                                 JavaCore.ENABLED );
                    Map cfo = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
                    options.putAll( cfo );
                    options.put( DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_PACKAGE,
                                 "1" );
                }
                return options;
            }

        };
        String mergexml = JMergerTest.class.getResource( "merge.xml" ).getFile();
        model.initialize( astFacadeHelper, mergexml );
        JMerger jMerger = new JMerger(model);
        try
        {
            jMerger.setSourceCompilationUnit( jMerger.createCompilationUnitForInputStream( 
                                                            new FileInputStream( src )));
            jMerger.setTargetCompilationUnit( jMerger.createCompilationUnitForInputStream( 
                                                            new FileInputStream(target)));
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }
        jMerger.merge();
        String contents = jMerger.getTargetCompilationUnit().getContents();
        System.out.println(contents);
    }

    public static void main( String[] args )
    {
        File src = new File("HelloSrc.java" );
        File target = new File("HelloTarget.java");

        JMergerTest.merge( src, target );
    }
}

结果:
package hello;

public class Hello 
{
    
   public void say(){
       System.out.println("hello world");
   }
   /**
    * @generated
    */
   public void sayHelloTo(String name){
        System.out.println("Hello," + name);
    }
   public void test(){
        
    }
}

参考http://www.ibm.com/developerworks/library/os-ecemf3/
上面有更详细的介绍,但代码使用的版本有点老。
1
1
分享到:
评论

相关推荐

    Simulink仿真及代码生成技术入门到精通

    完整清晰版。全书共19章,分为入门篇、进阶篇和高级篇3个篇章。入门篇介绍Simulink软件...高级篇重点介绍“基于模型设计”的开发流程、嵌入式C代码生成技术原理及TLC语言编写方法,并展示如何在嵌入式应用中使用TSP。

    Simulink仿真代码生成技术入门到精通

    学习simulink仿真代码生成的好书!作者的写作风格贴合实战经验,具有很强的实操性。

    Simulink仿真及代码生成技术_随书程序.rar

    本资源“Simulink仿真及代码生成技术_随书程序.rar”显然是与Simulink相关的学习材料,可能包含了实例模型、源代码以及相关的教程内容。下面将详细介绍Simulink的关键知识点和代码生成技术。 1. **Simulink简介**:...

    C#代码生成器

    二、C#代码生成器的使用步骤 1. 设计模板:首先,用户需要设计或选择合适的代码生成模板,模板可以包含基本的类结构、属性、方法等元素。 2. 配置参数:根据项目需求,配置生成代码的相关参数,如命名空间、类名、...

    Matlab——Simulink仿真及代码生成技术入门到精通_第三章 Simulink高级篇(1-8).rar

    《Matlab Simulink仿真及代码生成技术入门到精通》第三章主要涵盖了Simulink的高级功能,包括代码生成的控制、代码可读性的提升、生成代码的文件结构解析、ERT下默认配置的理解以及rtw文件的相关操作。以下是对这些...

    动软.Net代码生成器

    动软.Net代码生成器源码的开放,对于.NET开发者来说,不仅意味着可以免费获取和使用这款工具,更重要的是,可以学习到代码生成技术的实现细节,提升自身的编程技能。通过研究源码,开发者可以了解到如何利用.NET 2.0...

    Simulink代码生成技术资料

    学习Simulink代码生成技术,不仅能够提升设计能力,还能缩短产品开发周期,降低维护成本。在实际工程应用中,例如汽车电子系统、航空航天控制、通信系统等领域,Simulink代码生成都有着广泛的应用。通过深入研究提供...

    UC广播代码生成器。一个给UC聊天室做的广播代码生成软件。

    7. **编程技术**:代码生成器的开发涉及到编程语言(如C#、Java等)、GUI设计(如WinForms、Qt等)以及可能的网络通信协议知识。 8. **应用范围**:虽然主要用于UC聊天室,但类似的代码生成器概念也可以应用于其他...

    懒人C51代码生成器

    2. **更多精品资源.txt**:这可能是一个包含额外学习资源和教程链接的文本文件,为用户提供更多的学习材料和参考资料,帮助他们在使用懒人C51代码生成器的同时,进一步提升自己的技能。 3. **单片机论坛.url**:这...

    基于深度学习的Web用户界面代码生成技术研究.pdf

    深度学习技术近年来在诸多领域取得了巨大成功,特别是在图像识别领域,深度学习模型能够实现对图像内容的精准理解,并据此生成对应的代码序列。本文探讨了基于深度学习技术的Web用户界面(WebUI)代码生成技术的研究...

    基于C#的WebFirst代码生成器设计源码

    本设计源码提供了一个基于C#的WebFirst代码生成器。...文件类型包括378个JavaScript脚本文件、138个SCSS样式文件、108个C#源...适合用于学习和实践C#、JavaScript、CSS、HTML和Shell技术,以及开发代码生成相关的系统。

    simulink代码生成步骤

    二、代码生成设置 Simulink提供了两种代码生成器:GRT和ERT。GRT是Simulink Coder,ERT是Embedded Coder。我们一般选择ERT,因为它提供了更多的配置选项,可以优化代码生成。 三、Report设置 Report是代码生成的...

    编译原理中间代码生成报告

    本报告主要关注如何在实验二的基础上,为赋值语句、if语句和while语句生成四元式中间代码。 一、实验目的 实验的主要目标是扩展原有的编译器功能,使其能够对已识别的赋值语句、if语句和while语句进行语义分析,并...

    Simulink仿真及代码生成技术_随书程序

    通过《Simulink仿真及代码生成技术入门到精通》这本书的学习,读者不仅可以掌握Simulink的基本操作,还能深入了解其在系统仿真、代码生成和嵌入式系统开发中的应用,为实际工程问题提供强大的解决方案。书中的随书...

    动软代码生成器的开源源码

    "动软代码生成器"是一款高效实用的软件开发工具,其开源源码为开发者提供了深入学习和交流的机会。代码生成器在IT行业中扮演着重要的角色,它能够自动生成常见的业务逻辑代码,极大地提高了开发效率,减少了手动编写...

    DSNF代码生成啊啊

    【标题】"DSNF代码生成啊啊"似乎指的是某种特定的代码生成技术或者工具,但提供的信息过于简略,无法直接解析出详细的技术点。不过,我们可以从“代码生成”这个概念来展开讨论。 代码生成是指通过自动化工具或程序...

    伪代码生成器PseudoCodeTool

    适用于java/C/C++等代码,源代码为java代码通过运行代码将代码输入程序框中D盘自动生成伪代码文件PseudoCode.txt。(注意:由于是简单代码只可适用于糊弄老师,实验报告等,不可用于学术研究)。

    和平之翼代码生成器SM版新版0.7.12

    和平之翼代码生成器是无垠式代码生成器的第二代,轻量级定制版的代码生成器。 他有如下的特点 1)每个版本都是单一技术栈支持。分为不同版本。本版是SpingMVC Spring Mybati技术栈。 2)比无垠式代码生成器更美观的...

    零基础速成simulink代码生成-结合CANOE的DBC文件CAN报文代码生成 移植到硬件4 模型

    零基础速成simulink代码生成——结合CANOE的DBC文件CAN报文代码生成 移植到硬件4 模型;此专栏面向嵌入式工程没有matlab开发经验的人,可以快速学习和实践这门技术。MDB技术,越来越成熟和普遍,从手写代码转到基于...

Global site tag (gtag.js) - Google Analytics