通过一些规则来确保将 UML 概要文件正确应用于目标模型的模型到模型变换的详细信息

如果变换操作将更新现有模型而不是创建新模型或者覆盖现有模型,那么必须谨慎地将 UML 概要文件应用于新生成的模型和现有目标模型的 in-memory 版本,在执行合并操作时会将这些模型装入内存中。这些 in-memory 模型必须引用每个 UML 概要文件的同一个 in-memory 实例,否则将不能合并这些模型。

运行模型到模型映射变换将生成一个临时 in-memory 模型。如果此模型的内容与文件系统中现有目标模型的内容不同,那么在执行变换后处理期间就会合并这两个模型。缺省合并过程是模型到模型变换框架中提供的一项变换规则,它会将现有目标模型装入内存,并使用结构化合并功能将此模型与生成的 in-memory 模型组合在一起。通过结构化合并获得的模型将替换现有目标模型。

模型中通常包含对其他模型中的对象的引用。例如,UML 模型中可能包含对 UML 概要文件中定义的构造型的引用,它也可能包含对 UML 库中定义的基本类型的引用。仅当这些跨模型引用将引用同一对象的同一 in-memory 实例时,结构化合并功能才会检测它们是否引用了该对象。

例如,假定已将 «Perspective» 构造型(它是在名为 Default 的 UML 概要文件中定义的)应用于已生成的 in-memory 模型中的 ExamplePackage 包,并且还应用于现有目标模型中的同一个包。将现有目标模型装入到用于结构化合并功能的内存之后,就解析了对 «Perspective» 构造型的引用。如果结构化合并功能未标识所生成的 in-memory 模型引用的内存中构造型对象的完全相同实例,那么结构化合并功能将无法检测是否对两个版本的 ExamplePackage 包都应用了同一构造型。缺省情况下,如果结构化合并功能检测到由要合并的模型装入并引用的同一模型的重复实例(例如,此示例中的 UML Default 概要文件),那么结构化合并功能就会停止。

为了避免存在同一模型的重复 in-memory 实例,应确保包含 in-memory 模型的资源集只具有每个模型的一个实例。

此样本变换项目提供了两项变换规则来确保正确应用了 UML 概要文件:
  • UMLDefaultLibrariesAddRule:使用此规则按照一致的方式将缺省 UML 库和概要文件添加至已生成的 in-memory 模型。
  • CrossModelReferenceCheckRule:使用此规则来验证已生成的模型不存在位于其资源集外部的跨模型引用。将已生成的 in-memory 模型与现有目标模型的 in-memory 版本进行合并时,这种外部引用可能会导致问题。

这些规则位于 com.ibm.xtools.transform.authoring 包中。有关这些规则的更多信息,请参阅 Rational Transformation Authoring Developer Guide API Reference。此样本中的变换同时使用了这些规则。探究已生成的变换源代码以了解它们在您可以定制的变换源代码的各个部分中的实例化。

下列代码段说明了如何使用 UMLDefaultLibrariesAddRule 规则。

以下代码段说明了已生成的 Model2ModelTransform 类中的 addTransformElements 方法的缺省实现;缺省类中不包含规则。在已生成的 Model2ModelTransform 类中,addTransformElements 方法将实例化此规则:
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    private void addTransformElements(Registry registry) {
      // You may add more transform element before the generated ones here
    	// Remember to remove the @generated tag or add NOT to it
    	addGeneratedTransformElements(registry);
    	// You may add more transform element after the generated ones here
    	// Remember to remove the @generated tag or add NOT to it
    }
以下代码段说明了 addTransformElements 方法如何实例化此规则:
注: 为了防止源代码生成过程覆盖对代码所作的更改,必须除去 @generated 标记或者修改此标记,如以下代码段中所示。
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated NOT
     */
    private void addTransformElements(Registry registry) {
      add(new UMLDefaultLibrariesAddRule());
      // You may add more transform element before the generated ones here
    	// Remember to remove the @generated tag or add NOT to it
    	addGeneratedTransformElements(registry);
    	// You may add more transform element after the generated ones here
    	// Remember to remove the @generated tag or add NOT to it
    }
以下代码段显示了已生成的 TransformationProvider 类的 createRootTransformation 方法的原始版本,但是没有 CrossModelReferenceCheckRule 规则:
注: 在此样本中,TransformationProvider 类被命名为 copyprofileTransformationProvider。
    /**
     * Creates a root transformation. You may add more rules to the transformation here
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @param transform The root transformation
     * @generated
     */
    protected RootTransformation createRootTransformation(ITransformationDescriptor descriptor) {
        // Create and return an instance of a class that extends RootTransformation 
        // and handles source objects of type = (resource) and target objects of type = (resource)
        // and remove the @generated tag.  The default implementation provided here is
        // for source and target objects of type = (resource).
        return new RootTransformation(descriptor, new MainTransform()){
            protected void addPostProcessingRules() {
                add(new UMLProfilesConsistencyCheckRule());
                super.addPostProcessingRules();
            }};
    }
以下代码段显示了 createRootTransformation 方法中 CrossModelReferenceCheckRule 规则的实例化:
注: 在此样本中,TransformationProvider 类被命名为 copyprofileTransformationProvider。
    /**
     * Creates a root transformation. You may add more rules to the transformation here
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @param transform The root transformation
		 * @generated NOT
     */
    protected RootTransformation createRootTransformation(ITransformationDescriptor descriptor) {
        // Create and return an instance of a class that extends RootTransformation 
        // and handles source objects of type = (resource) and target objects of type = (resource)
        // and remove the @generated tag.  The default implementation provided here is
        // for source and target objects of type = (resource).
        return new RootTransformation(descriptor, new MainTransform()){
            protected void addPostProcessingRules() {
                add(new CrossModelReferenceCheckRule());
                add(new UMLProfilesConsistencyCheckRule());
                super.addPostProcessingRules();
            }};
    }
缺省情况下,如果 CrossModelReferenceCheckRule 规则发现已生成的 in-memory 模型中的一个引用在现有目标模型的同一资源集中未被解析,那么此规则就会抛出异常。要查看此异常,请完成下列步骤:
  1. 在名为 Model2Model 的变换类中,将 UMLDefaultLibrariesAddRule 规则注释掉。
  2. 运行变换。
变换将抛出异常并停止运行,因为已生成的 in-memory 模型引用了 UML 原语库,而此模型的资源集并不包含此原语库。

反馈