`

EMF--JMerger

    博客分类:
  • EMF
阅读更多
Eclipse Modeling Framework(EMF)中包含了一个开放源代码的工具 JMerge(org.eclipse.emf.codegen.merge.java.JMerger),这个工具可以使代码生成更加灵活,可定制性更好。本文使用一个例子来展示如何将 JMerge 添加到一个应用程序中,并为不同的环境定制 JMerge 的行为。
    前面几篇文章介绍了有关 Eclipse 的 Java Emitter Templates (JET)和代码生成的知识,在那几篇文章中,您已经看到如何通过使用模板和代码生成器来节省时间,并实现模式级的代码重用。然而在大部分情况中,这都还不够。您需要能够将所生成的代码插入现有的代码中,或者允许以后的开发人员来定制所生成的代码,而不需要在重新生成代码时重新编写任何内容。理想情况下,代码生成器的创建者希望可以支持今后开发人员所有的需求:从修改方法的实现、修改各种方法签名,到修改所生成类的继承结构。这是一个非常有趣的问题,目前还没有很好的通用解决方案;但是有一个很好的纯 Java 的解决方案,称为 JMerge(Java Merge)。应用场景:现在想允许用户定制所生成的测试类;然而在原有类的接口发生变化时,仍然需要重新生成代码。要实现这种功能,可以使用 JMerge。
    从插件中调用 JMerge 的代码非常简单:
private static final String JMerger_Config = "com/yapulan/jfes/jmerge/merge.xml";
// 模板生成的文件
		File src = new File("generated-jmergesrc/com/yapulan/jfes/jmerge/Hello.java.gen");

		// 生成的代码文件
		File target = new File("generated-jmergesrc/com/yapulan/jfes/jmerge/Hello.java");
JControlModel model = new JControlModel();
		ASTFacadeHelper astFacadeHelper = new ASTFacadeHelper() {
			Map<String, String> options;

			@SuppressWarnings("unchecked")
			@Override
			public Map getJavaCoreOptions() {
				if (logger.isDebugEnabled()) {
					logger.debug("getJavaCoreOptions() - start");
				}

				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");
				}

				if (logger.isDebugEnabled()) {
					logger.debug("getJavaCoreOptions() - end");
				}
				return options;
			}

		};
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		model.initialize(astFacadeHelper, UtilTools.saveUrlAsFile(loader.getResourceAsStream(JMerger_Config)).getPath());
		JMerger jMerger = new JMerger(model);

		jMerger.setSourceCompilationUnit(jMerger.createCompilationUnitForInputStream(new FileInputStream(src)));
		jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForInputStream(new FileInputStream(target)));

		jMerger.merge();
		String contents = jMerger.getTargetCompilationUnit().getContents();

这会创建一个新的 JMerger 实例,以及一个 URI merge.xml,设置要合并的来源和目标,并调用 merger.merge()。然后合并的内容就可以展开为 merger.getTargetCompilationUnit()。
merge.xml:
<?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)erated\s*\n" />

	<merge:dictionaryPattern name="generatedUnmodifiableMembers"
		select="Member/getComment" match="\s*@\s*(unmod)ifiable\s*\n" />

	<merge:pull sourceMarkup="^unmod$" sourceGet="Member/getFlags"
		targetPut="Member/setFlags" />


	<!-- if target is generated, transfer -->
	<!-- change to sourceMarkup if the source is the standard -->
	<merge:pull targetMarkup="^gen$" sourceGet="Method/getBody"
		sourceTransfer="(\s*//\s*begin-user-code.*?//\s*end-user-code\s*)\n"
		targetPut="Method/setBody" />

	<!--
		copy comments except between the begin-user-doc and end-user-doc tags
	-->
	<merge:pull sourceMarkup="^gen$" sourceGet="Type/getComment"
		sourceTransfer="(\s*&lt;!--\s*begin-user-doc.*?end-user-doc\s*-->\s*)\n"
		targetMarkup="^gen$" targetPut="Type/setComment" />

	<!-- force transfer of all unmodifiable elements -->
	<merge:pull sourceMarkup="^unmod$" sourceGet="Method/getBody"
		targetPut="Method/setBody" />

</merge:options>

sourceGet 必需的。该值必须是 附录 A 中列出的一个选项,如 "Member/getBody"。
targetPut 必需的。该值必须是 附录 A 中列出的一个选项,如 "Member/setBody"。
sourceMarkup 可选的。用来在触发 merge:pull 规则之前过滤必须匹配源代码的 dictionaryPatterns 。格式如 "^dictionaryName$",也可以使用 "|" 将多个 dictionaryPatterns 合并在一行中。
targetMarkup 可选的。用来在触发 merge:pull 规则之前过滤必须匹配目标代码的 dictionaryPatterns。格式如 "^dictionaryName$",也可以使用 "|" 将多个 dictionaryPatterns 合并在一行中。
sourceTransfer 可选的。一个正则表达式,指定要传递给目标代码的源代码的数量。

Hello.java.gen:
/**
 * 辅助文件头部分,不可修改。
* @generated
*/
public class Hello {
	
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String aa;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void say() {
	
		System.out.println("测试不容许修改代码!");		
		
		// begin-user-code
		
		// end-user-code
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @unmodifiable
	 */
	public void sayHelloTo(String name) {
	
		System.out.println("测试不容许修改代码!" + name);	

	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @unmodifiable
	 */
	public void sayHelloTo1(String name) {
	
		System.out.println("测试不容许修改代码!" + name);	

	}

	public void test() {

	}
}

Hello.java:
public class Hello {
	
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String aa;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void say() {
	
		System.out.println("测试不容许修改代码!");		
		// begin-user-code
			System.out.println("添加11111任何代码!");			
		// end-user-code
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @unmodifiable
	 */
	public void sayHelloTo(String name) {
	
		System.out.println("测试不容许修改代码!" + name);	

	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @unmodifiable
	 */
	public void sayHelloTo1(String name) {
	
		System.out.println("测试不容许修改代码!" + name);	

	}

	public void test() {

	}
}
2
1
分享到:
评论

相关推荐

    emf-sdo-xsd-SDK-2.3.2.zip

    《Eclipse插件开发与应用:深入理解emf-sdo-xsd-SDK-2.3.2》 在软件开发领域,Eclipse作为一款强大的开源集成开发环境(IDE),因其高度可扩展性和丰富的插件生态而深受开发者喜爱。Eclipse插件是其核心功能之一,...

    emf-xsd-SDK-2.6.1

    在"emf-xsd-SDK-2.6.1"的压缩包中,包含了Eclipse环境的相关文件,这通常意味着我们可以在这个环境中开发和测试基于EMF和XSD的模型应用。Eclipse是一个集成开发环境(IDE),支持多种编程语言和插件,EMF相关的插件...

    emf-sdo-SDK-2.2.2

    `emf-sdo-SDK-2.2.2`是EMF对SDO标准的实现,是一个针对Eclipse环境的插件。 在Eclipse中,`emf-sdo-SDK-2.2.2`主要包含以下几个方面的知识点: 1. **元模型(Metamodel)**:元模型是描述数据结构的模型,它定义了...

    emf-sdo-SDK-2.2.0(2) eclipse 可视化 界面设计

    emf-sdo-SDK-2.2.0(2) eclipse 可视化 界面设计。 因为size太大,所以分成了2部分,另一部分在 emf-sdo-SDK-2.2.0(1)里面。 emf-sdo-SDK-2.2.0(1)的下载地址: http://download.csdn.net/source/1002774

    emf-runtime-2.6.1.7z

    Eclipse 3.6.1(Helios)的插件。emf-runtime-2.6.1.7z。

    emf-sdo-xsd-SDK-2.0.1.zip

    在EMF-SDO-XSD SDK中,"eclipse"可能指的是Eclipse集成开发环境(Integrated Development Environment),这是一个广泛使用的Java开发工具,也支持多种其他语言和框架,包括Struts。开发者可以使用Eclipse来导入和...

    emf-runtime,eclipse modeling framework

    标题中提到的"emf-runtime"是指EMF运行时环境,它是EMF的核心组成部分,包含了运行时类库和API,用于支持模型对象的创建、操作和持久化。这个环境使得开发者能够在应用程序中使用EMF模型,而无需关心底层实现的复杂...

    emf-sdo-xsd-SDK-2.4.0.zip

    emf-sdo-xsd-SDK-2.4.0.zip emf是Eclipse modeling framework组建框架的缩写;SDO是服务数据对象的缩写,它是Java程序的一种数据编程框架;emf-sdo-xsd-SDK-2.4.0.zip是Eclipse编程器的组成员之一。

    emf-xsd-Update-2.10.2

    【标题】"emf-xsd-Update-2.10.2" 是一个与Java可视化开发相关的软件更新版本,主要用于支持Visual Editor的安装和使用。这个版本是2.10.2,通常代表着修复了一些已知问题,增加了新功能,或者优化了性能。 【描述...

    emf-xsd-Update-2.7.2

    【标题】"emf-xsd-Update-2.7.2" 涉及到的是一个针对Eclipse集成开发环境的扩展,主要关注的是EMF(Eclipse Modeling Framework)和XSD(XML Schema Definition)的更新版本2.7.2。这个更新包包含了对EMF框架的增强...

    emf-runtime-2.5.0.zip

    "emf-runtime-2.5.0.zip" 是一个包含EMF运行时库的压缩文件,版本为2.5.0。这个版本可能包含了对模型对象的创建、序列化、反序列化以及与模型相关的事件处理等功能。它对于那些希望在Eclipse环境下开发图形化编辑器...

    emf-sdo-runtime-2.2.0.zip

    "emf-sdo-runtime-2.2.0.zip" 是一个包含EMF SDO运行时库的压缩包,用于在Eclipse环境中集成SDO功能。这个版本号2.2.0表明这是一个特定的稳定版本,包含了该版本中所有修复的bug和新增的功能。 在压缩包内的...

    emf-runtime-2.6.1

    标题中的"emf-runtime-2.6.1"指的是EMF框架的运行时组件,版本号为2.6.1。 EMF的核心功能包括: 1. **模型定义**:通过扩展XML Schema Definition (XSD) 或者ECORE(EMF的元数据模型)来定义模型结构。ECORE是一种...

    emf-sdo-runtime

    `emf-sdo-runtime`是EMF针对SDO标准实现的运行时库,它是Eclipse IDE中的一个插件,用于支持在Eclipse环境中开发和使用SDO的应用。 EMF-SDO-Runtime的核心功能包括: 1. **数据对象模型**:它允许开发者定义复杂的...

    emf-sdo-runtime-2.2.0.zip、GEF-runtime-3.2.zip和VE-runtime-1.2.3_jem.zip

    myeclipse ,swing ,chajian,解压,添加

    emf-sdo-xsd-SDK-2.2.1

    标题中的"emf-sdo-xsd-SDK-2.2.1"指的是Eclipse Modeling Framework (EMF) Service Data Objects (SDO) XSD SDK的一个特定版本,即2.2.1。EMF是Eclipse基金会开发的一个强大的建模框架,它允许开发者创建、操作和...

    Eclipse-EMF-GEF资料.rar

    Eclipse-EMF-GEF 是一套用于构建图形化用户界面和模型驱动开发的强大工具集。这个压缩包包含了关于这三个关键技术的各种参考资料,帮助开发者深入理解并应用它们。 1. **Eclipse-EMF (Eclipse Modeling Framework)*...

    emf-sourcedoc

    【标题】:“EMF-Sourcedoc”:Java 可视化IDE插件解析与应用 【描述】:“EMF-Sourcedoc”是一个专为Java开发者设计的高效集成开发环境(IDE)插件,它提供了强大的可视化功能,帮助程序员更直观地理解和编辑模型...

Global site tag (gtag.js) - Google Analytics