`

代码生成技术学习之二 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仿真及代码生成技术入门到精通.pdf_孙忠潇

    《Simulink仿真及代码生成技术入门到精通》围绕Simulink软件的仿真和代码生成技术,从原理上展开阐述,把握整体,注重细节,让读者深刻认识Simulink的运行原理。结构化的章节安排和丰富多彩的案例展示了Simulink在...

    Simulink仿真及代码生成技术入门到精通 (2).zip

    《Simulink仿真及代码生成技术入门到精通》是一本专为嵌入式开发者准备的指导书籍,旨在帮助读者从基础到高级全面掌握Simulink的使用和代码生成技术。Simulink是MATLAB环境中的一个强大工具箱,主要用于动态系统建模...

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

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

    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代码生成都有着广泛的应用。通过深入研究提供...

    组织机构代码生成器

    "组织机构代码生成器"是一款专门设计用于自动生成这类代码的工具。这个工具的目的是帮助用户快速为新成立的机构或者需要更新信息的现有机构生成符合规范的组织机构代码。 生成器的功能通常包括以下几个关键方面: ...

    Simulink代码生成学习札记,simulink代码生成及编译,C,C++

    simulink 代码自动生成 非常好学 容易上手 全程零代码

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

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

    懒人C51代码生成器

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

    动软代码生成器C#连接mysql三层代码模板--修改版

    动软代码生成器 V2.76版,请支持正版。 修改DAL.cmt模板文件: 1、必须增加该命名空间 using MySql.Data.MySqlClient; 2、部分的 SqlParameter 修改为 MySqlParameter 3、获取前几行数据时,修改为 limit 4、参数...

    基于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是代码生成的...

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

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

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

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

Global site tag (gtag.js) - Google Analytics