`

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

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

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

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

    C#代码生成器

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

    asp.net 代码生成器 .NET代码生成器 C#代码生成器 三层源代码生成器

    asp.net 代码生成器 【基本说明】 1、能够生成三层模式操作的所有后台代码,简单的SQL Server 2005数据库操作。 2、生成的代码包括了 MODEL、BLL、DAL、DBHelper、Config 生成的代码内有详细注释可提供参考。 ...

    组织机构代码生成器

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

    垃圾代码生成器

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

    Matlab——Simulink仿真及代码生成技术入门到精通_第二章 Simulink进阶篇(5-8).rar

    在Matlab的Simulink环境中,用户可以进行高级的系统级仿真和代码生成,这是Simulink的强大之处。本资源包包含的四个视频教程聚焦于Simulink的进阶使用,旨在帮助用户从初级到精通掌握Simulink的仿真和代码生成技术。...

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

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

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

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

    Nfine 代码生成器 NFine MSSQL_T4代码生成器,很方便开发。

    NFine 代码生成器是一款专为开发者设计的高效工具,主要针对MSSQL数据库,采用T4模板技术,极大地简化了编码过程,提高了开发效率。该工具的核心功能是自动生成基于MSSQL数据库的各类代码,包括但不限于实体类、DAL...

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

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

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

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

    伪代码生成器PseudoCodeTool

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

    乐谱代码生成软件 乐谱代码生成软件

    9. **学习与教育**:对于教育领域,乐谱代码生成软件能帮助教师创建练习材料,学生则可以更方便地查看、修改和演奏乐谱。 10. **协作与共享**:部分软件提供了云同步功能,让多人可以同时编辑同一份乐谱,方便团队...

Global site tag (gtag.js) - Google Analytics