Detalles para una transformación de modelo a modelo con reglas que garanticen que los perfiles UML se aplican correctamente en los modelos de destino

Si la transformación actualiza un modelo existente en vez de crear un modelo nuevo o de sobrescribir el existente, deben aplicarse correctamente los perfiles UML a las versiones en memoria del nuevo modelo generado y del modelo de destino existente, que se carga en la memoria durante la operación de fusión. Estos modelos en memoria deben hacer referencia a la misma instancia en memoria de cada perfil UML, de lo contrario, los modelos no se fusionarán.

La ejecución de una transformación de correlación de modelo a modelo genera un modelo temporal en memoria. Si los contenidos de este modelo son diferentes de los contenidos de un modelo de destino existente en el sistema de archivos, los modelos se fusionarán durante el postproceso. El procedimiento de fusión predeterminado, que es una regla de transformación que se proporciona en la infraestructura de transformación de modelo a modelo, carga el modelo de destino existente en la memoria y utiliza la funcionalidad de fusión estructural para combinarlo con el modelo generado en la memoria. El modelo resultante de una fusión estructural sustituye el modelo de destino existente.

A menudo, los modelos contienen referencias a objetos de otros modelos. Por ejemplo, un modelo UML puede contener referencias a estereotipos que se definen en perfiles UML, o puede contener referencias a tipos primitivos que se definen en bibliotecas UML. La fusión estructural detecta que estas referencias entre modelos hacen referencia al mismo objeto sólo si tienen la misma referencia en la instancia en memoria de ese objeto.

Por ejemplo, se supone que el estereotipo "Perspectiva", que se define en el perfil UML llamado Predeterminado, se aplica al paquete con nombre ExamplePackage de un modelo generado en memoria y también al mismo paquete en el modelo de destino existente. Cuando el modelo de destino existente se carga en la memoria para la fusión estructura, se resuelve la referencia al estereotipo "Perspectiva". Si la fusión estructural no identifica la misma instancia exacta del objeto estereotipo en la memoria que las referencias de modelo generadas en memoria, la fusión estructural no podrá detectar que a ambas versiones del paquete ExamplePackage se les aplica el mismo estereotipo. De forma predeterminada, la fusión estructural se detiene cuando detecta instancias duplicadas del mismo modelo, como el perfil UML predeterminado de este ejemplo, que se cargan y a las que hacen referencia otros modelos que se están fusionando.

Para evitar que las instancias de un modelo se dupliquen, asegúrese de que el conjunto de recursos que contiene los modelos en memoria sólo tenga una instancia por modelo.

Este proyecto de transformación de ejemplo proporciona dos reglas de transformación que garantizan la correcta aplicación de los perfiles UML:
  • UMLDefaultLibrariesAddRule: sirve para añadir las bibliotecas y perfiles UML predeterminados a un modelo generado en memoria de una forma coherente.
  • CrossModelReferenceCheckRule: sirve para verificar que un modelo generado no tenga referencias a otros modelos que sean externas al conjunto de recursos. Es probable que estas referencias externas provoquen algún problema al fusionar un modelo generado en memoria y la versión en memoria del modelo de destino existente.

Estas reglas se encuentran en el paquete denominado com.ibm.xtools.transform.authoring. Para obtener más información sobre estas reglas, vea la publicación de consulta Rational Transformation Authoring Developer Guide API Reference. La transformación de este ejemplo utiliza ambas reglas. Examine el código fuente de la transformación para ver si hay instanciación en las secciones del código fuente de la transformación que pueda personalizar.

En los fragmentos de código siguientes se muestra cómo utilizar la regla denominada UMLDefaultLibrariesAddRule.

En el siguiente fragmento de código se muestra la implementación predeterminada del método denominado addTransformElements en la clase generada Model2ModelTransform. La clase predeterminada no contiene esta regla. En la clase generada que se llama Model2ModelTransform, el método addTransformElements crea instancias de la regla:
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    private void addTransformElements(Registry registry) {
      // Aquí puede añadir más elementos de transformación antes de los generados
    	// Recuerde que debe eliminar la etiqueta @generated o añadirle NOT
    	addGeneratedTransformElements(registry);
    	// Aquí puede añadir más elementos de transformación después de los generados
    	// Recuerde que debe eliminar la etiqueta @generated o añadirle NOT
    }
En el siguiente código de fragmento se muestra cómo el método denominado addTransformElements crea instancias de la regla:
Nota: Para evitar que el proceso de generación de código fuente sobrescriba los cambios en el código, debe eliminar la etiqueta @generated, o bien modificarla según se muestra en el fragmento de código siguiente.
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated NOT
     */
    private void addTransformElements(Registry registry) {
      add(new UMLDefaultLibrariesAddRule());
      // Aquí puede añadir más elementos de transformación antes de los generados
    	// Recuerde que debe eliminar la etiqueta @generated o añadirle NOT
    	addGeneratedTransformElements(registry);
    	// Aquí puede añadir más elementos de transformación después de los generados
    	// Recuerde que debe eliminar la etiqueta @generated o añadirle NOT
    }
En el fragmento de código siguiente se muestra la versión original del método createRootTransformation de la clase generada TransformationProvider, sin la regla CrossModelReferenceCheckRule:
Nota: En el ejemplo, la clase TransformationProvider se denomina copyprofileTransformationProvider.
    /**
     * Crea una transformación raíz. Aquí se pueden añadir más reglas de la transformación
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @param transform The root transformation
     * @generated
     */
    protected RootTransformation createRootTransformation(ITransformationDescriptor descriptor) {
        // Cree y devuelva una instancia de una clase que amplía RootTransformation 
        // y gestiona los objetos de origen de tipo = (recurso) y objetos de origen de tipo = (recurso)
        // y elimine la etiqueta @generated.  La implementación predeterminada que se proporciona aquí es
        // para los objetos de origen y destino de tipo = (recurso).
        return new RootTransformation(descriptor, new MainTransform()) {
            protected void addPostProcessingRules() {
                add(new UMLProfilesConsistencyCheckRule());
                super.addPostProcessingRules();
            }};
    }
El fragmento de código siguiente muestra la instanciación de la regla CrossModelReferenceCheckRule en el método createRootTransformation:
Nota: En el ejemplo, la clase TransformationProvider se denomina copyprofileTransformationProvider.
    /**
     * Crea una transformación raíz. Aquí se pueden añadir más reglas de la transformación
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @param transform The root transformation
		 * @generated NOT
     */
    protected RootTransformation createRootTransformation(ITransformationDescriptor descriptor) {
        // Cree y devuelva una instancia de una clase que amplía RootTransformation 
        // y gestiona los objetos de origen de tipo = (recurso) y objetos de origen de tipo = (recurso)
        // y elimine la etiqueta @generated.  La implementación predeterminada que se proporciona aquí es
        // para los objetos de origen y destino de tipo = (recurso).
        return new RootTransformation(descriptor, new MainTransform()) {
            protected void addPostProcessingRules() {
                add(new CrossModelReferenceCheckRule());
                add(new UMLProfilesConsistencyCheckRule());
                super.addPostProcessingRules();
            }};
    }
De forma predeterminada, la regla denominada CrossModelReferenceCheckRule ejecuta una excepción, si descubre una referencia en el modelo generado en memoria que no se resuelve en el mismo conjunto de recursos que el modelo de destino existente. Para ver esta excepción, efectúe los pasos siguientes:
  1. En la clase de transformación denominada Model2Model, comente la regla denominada UMLDefaultLibrariesAddRule.
  2. Ejecute la transformación.
La transformación ejecuta una excepción y detiene la ejecución porque el modelo generado en memoria hace referencia a la biblioteca Primitivos UML, pero el conjunto de recursos de este modelo no contiene la biblioteca Primitivos.

Comentarios