`

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

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

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

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

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

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

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

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

    Simulink代码生成技术资料

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

    组织机构代码生成器

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

    垃圾代码生成器

    总的来说,【iOS垃圾代码生成器】作为一种技术手段,虽然在特定场景下可能有用,但其合法性、可持续性和潜在风险都应引起开发者的重视。在实际应用中,开发者应当遵守平台规则,注重应用的质量和用户体验,避免采取...

    懒人C51代码生成器

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

    时空之门前端代码生成器4.5独立版Beta10版。三大变形功能群齐备。

    时空之门前端代码生成器,是第四代动词算子式代码生成器,经过彻底的重构的先进动词算子式代码生成器,也是专用的Vue+ElementUI前端代码生成器,可以和多种后端代码生成器搭配。和平之翼和光对前端代码生成的支持是...

    simulink代码生成步骤

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

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

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

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

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

    DSNF代码生成啊啊

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

    伪代码生成器PseudoCodeTool

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

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

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

    最新版java代码生成器基于springMvc+mysql 后台功能一键生成

    最新版java代码生成器基于springMvc+mysql 后台功能一键生成 压缩包里的jdk文件目录 请自行下载jdk1.8.0_45版本并覆盖进去 没有jdk是运行不起来的 也可以下载其他jdk版本 但是jdk1.8.0_45这个文件目录名称不要更改 ...

    simulink仿真及代码生成技术pdf和随书程序

    这个压缩包包含的资源——"Simulink仿真及代码生成技术入门到精通.pdf"是一本详细教程,配合随书程序,旨在帮助学习者从基础到高级掌握Simulink的相关技能。 1. **Simulink界面介绍**:Simulink的用户界面提供了...

Global site tag (gtag.js) - Google Analytics