Dettagli relativi a una trasformazione modello-a-modello con regole che assicurano la corretta applicazione dei profili UML ai modelli di destinazione

Se la trasformazione aggiorna un modello di destinazione esistente anziché creare un nuovo modello o sovrascrivere quello esistente, i profili UML devono essere applicati con attenzione alle versioni in memoria del nuovo modello generato e del modello di destinazione esistente, che viene caricato durante l'operazione di unione. Questi modelli in memoria devono fare riferimento alla stessa istanza in memoria di ciascun profilo UML, altrimenti non sarà possibile unire i modelli.

L'esecuzione di una trasformazione di associazione modello-a-modello genera un modello in memoria temporaneo. Se il contenuto di questo modello è diverso da quello di un modello di destinazione esistente nel file system, i modelli vengono uniti durante la post-elaborazione della trasformazione. La procedura di unione predefinita, che è una regola di trasformazione fornita nel framework di trasformazione modello-a-modello, carica il modello di destinazione esistente nella memoria e utilizza la funzionalità di unione strutturale per combinarlo con il modello in memoria generato. Il modello ottenuto dall'unione strutturale sostituisce il modello di destinazione esistente.

I modelli spesso contengono riferimenti a oggetti presenti in altri modelli. Ad esempio, un modello UML potrebbe contenere riferimenti a stereotipi che sono definiti nei profili UML oppure potrebbe contenere riferimenti ai tipi primitive che sono definiti nelle librerie UML. L'unione strutturale rileva che i riferimenti ai modelli incrociati fanno riferimento allo stesso oggetto solo se fanno riferimento alla stessa istanza in memoria di quell'oggetto.

Ad esempio, si supponga che lo stereotipo «Prospettiva», che è definito nel profilo UML denominato Predefinito, sia applicato al package ExamplePackage in un modello in memoria generato e anche allo stesso package nel modello di destinazione esistente. Quando il modello di destinazione esistente viene caricato in memoria per l'unione strutturale, il riferimento allo stereotipo «Prospettiva» viene risolto. Se l'unione strutturale non identifica esattamente la stessa istanza dell'oggetto stereotipo in memoria cui fa riferimento il modello in memoria generato, l'unione strutturale non può rilevare che ad entrambe le versioni del package ExamplePackage è applicato lo stesso stereotipo. Per impostazione predefinita, l'unione strutturale si interrompe quando rileva istanze duplicate dello stesso modello quali, ad esempio, il profilo Predefinito UML di questo esempio, che sono caricate e a cui fanno riferimento i modelli di cui si sta eseguendo l'unione.

Per impedire istanze in memoria duplicate di un modello, assicurarsi che l'insieme di risorse che contiene i modelli in memoria abbia solo un'istanza di ciascun modello.

Questo progetto di trasformazione di esempio fornisce due regole di trasformazione per assicurare che i profili UML vengano applicati correttamente:
  • UMLDefaultLibrariesAddRule: utilizzare questa regola per aggiungere in maniera coerente le librerie UML predefinite e i profili a un modello in memoria generato.
  • CrossModelReferenceCheckRule: utilizzare questa regola per verificare che un modello generato non abbia riferimenti ai modelli incrociati che siano esterni all'insieme di risorse di un insieme di risorse di un modello generato. Questi riferimenti esterni potrebbero causare problemi quando si uniscono un modello in memoria generato e una versione del modello di destinazione esistente.

Queste regole si trovano nel package denominato com.ibm.xtools.transform.authoring. Per ulteriori informazioni su queste regole, consultare il manuale Rational Transformation Authoring Developer Guide API Reference. La trasformazione in questo esempio utilizza entrambe queste regole. Esaminare il codice sorgente della trasformazione generata per osservare la creazione di istanze nelle sezioni del codice sorgente della trasformazione che è possibile personalizzare.

I successivi frammenti di codice mostrano come utilizzare la regola denominata UMLDefaultLibrariesAddRule.

Il seguente frammento di codice mostra l'implementazione predefinita del metodo addTransformElements nella classe generata denominata Model2ModelTransform; la classe predefinita non contiene la regola. Nella classe generata denominata Model2ModelTransform, il metodo addTransformElements crea un'istanza della regola:
    /**
     * <!-- 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
    }
Il seguente frammento di codice mostra in che modo il metodo addTransformElements crea un'istanza della regola:
Nota: per impedire che il processo di generazione del codice sorgente sovrascriva le modifiche al codice, è necessario rimuovere il tag @generated oppure modificarlo come mostrato nel frammento riportato di seguito.
    /**
     * <!-- 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
    }
Il seguente frammento di codice mostra la versione originale del metodo createRootTransformation della classe TransformationProvider generata, senza la regola CrossModelReferenceCheckRule:
Nota: nell'esempio, la classe TransformationProvider è denominata 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();
            }};
    }
Il seguente frammento di codice mostra la creazione dell'istanza della regola CrossModelReferenceCheckRule nel metodo createRootTransformation:
Nota: nell'esempio, la classe TransformationProvider è denominata 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();
            }};
    }
Per impostazione predefinita, la regola denominata CrossModelReferenceCheckRule genera un'eccezione se rileva un riferimento nel modello di memoria generato che non è risolto, nello stesso insieme di risorse del modello di destinazione esistente. Per vedere questa eccezione, effettuare le seguenti operazioni:
  1. Nella classe di trasformazione denominata Model2Model, impostare come commento la regola UMLDefaultLibrariesAddRule.
  2. Eseguire la trasformazione.
La trasformazione genera un'eccezione e interrompe l'esecuzione in quanto il modello in memoria generato fa riferimento alla libreria Primitive UML, ma l'insieme di risorse di questo modello non contiene la libreria Primitive.
Argomento principale: Trasformazione modello-a-modello con regole che assicurano la corretta applicazione dei profili UML ai modelli di destinazione

Feedback