Skip to content

Cómo aplicar un UML Profile con QVT

mayo 10, 2012

He visto mucha gente preguntando, y pocas respuestas. Me parece algo básico de una transformación con UML, pero se ve que no está muy resuelto aún… qué raro, tecnología para model-driven verde?

Luego de mucho pelearme, y de mucha ayuda de Bea quien también se ha estado peleando los últimos años con esto, logré aplicar un perfil UML a un modelo de resultado en una transformación QVT. Hasta ahora no vi en ningún lado alguien que proponga hacer algo como lo que yo hago acá, entonces, no se si es la forma “correcta”, pero lo seguro que a mi sólo me ha funcionado siguiendo estos pasos. Si alguno tuvo mejor suerte con las otras formas de hacerlo, que avise 🙂

Primero que nada hay que tener los Metamodelos en ecore. Para eso ver esto y en caso que usen UTP ver esto también. Luego hay que registrarlos en Eclipse, para lo que hay que ir a Window -> Preferences -> QVT Metamodels -> y ahí agregarlos, tanto el de UTP como el de UML.

Segundo, la transformación que yo quiero hacer es de un diagrama de clases y como resultado otro diagrama de clases, pero con estereotipos aplicados de UTP. Entonces, el encabezado de la transformación QVT tendrá 3 parámetros, el archivo uml de entrada, el uml de UTP que tiene definido el profile, y el uml de salida que queremos generar.

Tercero, el siguiente código QVT

/* ------------------------------------------------------Generate Test Model */
top relation generateModel{
enforce domain target m:uml::Model{
name = 'TestModel'
};
}
/*--------------------------------------------------------- Generate Package */
top relation generatePackage{
enforce domain target p:uml::Package{
name = 'testing'
};
enforce domain target m:uml::Model{
packagedElement = p : uml::Package{
}
};
when{
generateModel(m);
}
}
/*--------------------------------------------------------- Generate Profile */
top relation generateProfileApplication{
checkonly domain profile prof:uml::Profile{
};
enforce domain target m:uml::Model{
profileApplication = pa : uml::ProfileApplication {
appliedProfile = prof
}
};
when{
generateModel(m);
}
/* ---------------------------------------------------------------------------------------------*/
Luego de esto les muestro un ejemplo de cómo aplicar el estereotipo DataPool a una clase.
/* ---------------------------------------------------------------------------------------------*/
top relation class2datapool {
varName : String;
m:uml::Model;
checkonly domain source class : uml::Class {
name = varName
};
enforce domain target dp_class : uml::Class{
name = 'test_'.concat(varName)--;
};
enforce domain target p:uml::Package{
packagedElement = dp_class : uml::Class{} --para que la clase quede en el paquete del modelo a generar
};
enforce domain target dp:utp::DataPool{
base_Classifier = dp_class -- class hereda de classifier
};
when{
generatePackage(p, m);
}
}

Lo curioso es que la cosa no termina acá. El archivo resultado tiene un problema, y según entendí es un problema conceptual más que de implementación.

El resultado no se ve con el profile aplicado, y si aplico a alguna clase un estereotipo (stereotype) como puede ser “DataPool”, este aparece como un  elemento suelto no reconocido. Ver la imagen:

Si vemos el archivo con un editor de texto:

<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:uml="http://www.eclipse.org/uml2/3.0.0/UML"
 xmlns:utp="http:///utp.ecore"
 xsi:schemaLocation="http://www.eclipse.org/uml2/3.0.0/UML
 ../Metamodels/OMG/Eclipse/uml.ecore
 http:///utp.ecore ../Metamodels/OMG/Eclipse/utp.ecore">
  <uml:Model xmi:id="_6nlFEJqbEeGnUZRcF-gJEA" name="TestModel">
    <packagedElement xmi:type="uml:Package" xmi:id="_6nlFEpqbEeGnUZRcF-gJEA" name="testing">
      <packagedElement xmi:type="uml:Class" xmi:id="_5-n_8JqhEeGnUZRcF-gJEA" name="test_clase1"/>
      <packagedElement xmi:type="uml:Class" xmi:id="_5-onAJqhEeGnUZRcF-gJEA" name="test_clase2"/>
      <packagedElement xmi:type="uml:Class" xmi:id="_5-onBJqhEeGnUZRcF-gJEA" name="test_clase3"/>
    </packagedElement>
    <profileApplication xmi:id="_5-pOEpqhEeGnUZRcF-gJEA">
      <appliedProfile href="../Metamodels/OMG/RSA/UTP_1.1_.uml#_oXP8sZqAEeGpn-jx1irnEw"/>
    </profileApplication>
  </uml:Model>
  <utp:DataPool xmi:id="_5-n_8pqhEeGnUZRcF-gJEA" base_Classifier="_5-n_8JqhEeGnUZRcF-gJEA"/>
  <utp:DataPool xmi:id="_5-onApqhEeGnUZRcF-gJEA" base_Classifier="_5-onAJqhEeGnUZRcF-gJEA"/>
  <utp:DataPool xmi:id="_5-pOEJqhEeGnUZRcF-gJEA" base_Classifier="_5-onBJqhEeGnUZRcF-gJEA"/>
</xmi:XMI>
Ahí se ve algo que me parece raro, que el profile que se referencia en appliedProfile no se está incluyendo. Al crear manualmente  el archivo que quiero lograr generar, se puede observar como diferencia que en el creado a mano (el correcto digamos) tiene referencia también al esquema del UTP.uml.
Entonces hay que hacer un pequeño cambio en la primer línea en negrita del archivo xml mostrado antes para poner esto:
 http:///utp.ecore ../Metamodels/OMG/RSA/UTP_1.1_.uml#_TbOMkJqWEeGnUZRcF-gJEA“>
donde es necesario poner el el token que se ve ahí en negrita también, el cual se obtiene del archivo UML, buscando el xmi:id del modelo con el profile. En mi caso lo saqué de una línea como esta:
 <contents xmi:type=”ecore:EPackage” xmi:id=”_TbOMkJqWEeGnUZRcF-gJEA” name=”utp”
Al hacer esto en el visor de UML de Eclipse puedo ver lo siguiente:
que claramente es lo que quería.
No me queda claro si estoy haciendo algo mal o si es un error de algún componente de la plataforma (que puede ir desde QVT, el visor UML o quién sabe qué más).
Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: