Detalhes para uma Transformação de Modelo em Modelo com Regras que Asseguram que Perfis UML Sejam Aplicados Corretamente a Modelos de Destino

Se a transformação atualiza um modelo existente em vez de criar um novo modelo ou sobrescrever o existente, os perfis UML devem ser aplicados cuidadosamente às versões em memória do novo modelo gerado e do modelo de destino existente, que é carregado na memória durante a operação de mescla. Esses modelos em memória devem fazer referência à mesma instância em memória de cada perfil UML, caso contrário, os modelos não podem ser mesclados.

Executar uma transformação de mapeamento de modelo em modelo gera um modelo em memória temporário. Se o conteúdo desse modelo for diferente do conteúdo de um modelo de destino existente no sistema de arquivos, os modelos são mesclados durante o pós-processamento da transformação. O procedimento de mescla padrão, que é uma regra de transformação fornecida na estrutura da transformação de modelo em modelo, carrega o modelo de destino existente na memória e utiliza a funcionalidade de mescla estrutural para combiná-la ao modelo em memória gerado. O modelo que resulta da mescla estrutural substitui o modelo de destino existente.

Os modelos freqüentemente contêm referências a objetos em outros modelos. Por exemplo, um modelo UML pode conter referências a estereótipos definidos nos perfis UML ou pode conter referências a tipos primitivos definidos nas bibliotecas UML. A mescla estrutural detecta que essas referências entre modelos fazem referência ao mesmo modelo somente se fizerem referência à mesma instância em memória desse objeto.

Por exemplo, suponhamos que o estereótipo «Perspectiva», definido no perfil UML denominado Padrão, seja aplicado ao pacote denominado ExamplePackage em um modelo em memória gerado e, também, ao mesmo pacote no modelo de destino existente. Quando o modelo de destino existente é carregado na memória para mescla estrutural, a referência ao estereótipo «Perspectiva» é resolvida. Se a mescla estrutural não identificar a mesma instância exata do objeto do estereótipo na memória ao qual o modelo em memória gerado faz referência, a mescla estrutural não pode detectar que ambas as versões do pacote ExamplePackage têm o mesmo estereótipo aplicado a elas. Por padrão, a mescla estrutural pára ao detectar instâncias duplicadas do mesmo modelo, como o perfil Padrão UML neste exemplo, que são carregadas e referidas pelos modelos que estão mesclando.

Para evitar instâncias em memória duplicadas de um modelo, assegure que o conjunto de recursos que contém os modelos em memória tenha somente uma instância de cada modelo.

Este projeto de transformação de amostra fornece duas regras de transformação para assegurar que perfis UML sejam aplicados corretamente:
  • UMLDefaultLibrariesAddRule: Utilize essa regra para incluir as bibliotecas e perfis UML padrão em um modelo em memória gerado de maneira consistente.
  • CrossModelReferenceCheckRule: Use esta regra para verificar se um modelo gerado não tem nenhuma referência entre modelos que são externos ao seu conjunto de recursos. Essas referências externas podem causar problemas quando um modelo em memória gerado e a versão em memória do modelo de destino existente são mesclados.

Essas regras estão localizadas no pacote denominado com.ibm.xtools.transform.authoring. Para obter informações adicionais sobre essas regras, consulte Rational Transformation Authoring Developer Guide API Reference. A transformação nesta amostra utiliza ambas as regras. Explore o código-fonte da transformação gerado para ver a instanciação nas seções do código-fonte da transformação que é possível customizar.

Os fragmentos de código a seguir mostram como utilizar a regra denominada UMLDefaultLibrariesAddRule.

O fragmento de código a seguir mostra a implementação padrão do método denominado addTransformElements na classe gerada denominada Model2ModelTransform; a classe padrão não contém a regra. Na classe gerada denominada Model2ModelTransform, o método denominado addTransformElements instancia a regra:
    /**
     * <!-- 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
    }
O fragmento de código a seguir mostra como o método denominado addTransformElements instancia a regra:
Nota: Para evitar o processo de geração de código-fonte para sobrescrever as alterações do código, você deve remover a tag @generated ou modificá-la, conforme mostrado no fragmento de código abaixo.
    /**
     * <!-- 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
    }
O fragmento de código a seguir mostra a versão original do método createRootTransformation da classe TransformationProvider gerada, sem a regra CrossModelReferenceCheckRule:
Nota: Na amostra, a classe TransformationProvider é denominada copyprofileTransformationProvider.
    /**
     * Creates a root transformation. É possível incluir mais regras na transformação aqui
     * <!-- 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();
            }};
    }
O fragmento de código a seguir mostra a instanciação da regra CrossModelReferenceCheckRule no método createRootTransformation:
Nota: Na amostra, a classe TransformationProvider é denominada copyprofileTransformationProvider.
    /**
     * Creates a root transformation. É possível incluir mais regras na transformação aqui
     * <!-- 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();
            }};
    }
Por padrão, a regra denominada CrossModelReferenceCheckRule emite uma exceção se descobrir uma referência no modelo em memória gerado que não é resolvido no mesmo conjunto de recursos que o modelo de destino existente. Para ver essa exceção, execute as etapas a seguir:
  1. Na classe de transformação denominada Model2Model, remova por comentário a regra denominada UMLDefaultLibrariesAddRule.
  2. Execute a transformação.
A transformação emite uma exceção e pára a execução, pois o modelo em memória gerado faz referência à biblioteca Primitivos UML, mas o conjunto de recursos desse modelo não contém a biblioteca Primitivos.

Feedback