Lenguajes de Transformación
-
Upload
jesussanchez -
Category
Technology
-
view
3.970 -
download
0
Transcript of Lenguajes de Transformación
Lenguajes de Transformación de Modelos
Eclipse Day2 de Diciembre de 2008, Valencia
Jesús Sánchez CuadradoGrupo modelumhttp://www.modelum.esUniversidad de Murcia
2/12/08 Jesús Sánchez Cuadrado 2
Transformación de modelos
Manipulación de un modelo
Ejemplos
Relaciones entre lenguajes
Sincronización de vistas en Eclipse
Lenguaje de alto nivel a artefactos de bajo nivel
Desarrollo basado en DSLs
Refactorizar modelos
Introducir superclase
Ingeniería inversa
Descubrir relaciones entre módulos
Manipulación en general de un modelo
El código fuente también es un modelo!
Utilizamos lenguajes de transformación de modelos
2/12/08 Jesús Sánchez Cuadrado 3
Transformación de modelos
Morigen Mdestino
MMorigen MMdestinoLenguaje
Transformación
Definición de transformación
<<conforma>> <<conforma>>
genera transforma
<<conforma>>
2/12/08 Jesús Sánchez Cuadrado 4
Transformación de modelos
PrimitiveDataType
AttributePackage
type
elems attrs
**
1
name: String
Classifier
name: String
Class
isPersistent: Bool
Schema
tbls
cols*
*1
name: String
Table
name: String
FKey
Column
name: Stringtype: String
pkey
0..1
refs
MetamodeloSimple UML
MetamodeloSimple RDBMS
Mapping
2/12/08 Jesús Sánchez Cuadrado 5
Lenguajes de transformación
Restricciones
Selección
self.license = #FreeSoftware and self.metamodel->include('Ecore')
Set { Java/EMF, ATL, QVTr, QVTo, Tefkat, Epsilon, Viatra, RubyTL }
2/12/08 Jesús Sánchez Cuadrado 6
Características
Tipo = { Imperativo, Declarativo, Híbrido }
Usabilidad
Entorno, instalación, etc.
Tipado
Manejo de errores
Bidireccional o unidireccional
Mecanismos de modularidad
Grano fino
Grano grueso
Consistencia incremental
Eficiencia
Compilación incremental
2/12/08 Jesús Sánchez Cuadrado 7
EMF + Java
Usar Java para manipular modelos Ecore
Aproximación de manipulación directa
Imperativo
El modelo se manipula con sentencias Java
Se puede crear un pequeño framework de soporte
Unidireccional
Usabilidad
Funciona. Eficiente.
Detalles de bajo nivel. Verboso.
Mecanismos de modularidad
Herencia, composición
2/12/08 Jesús Sánchez Cuadrado 8
EMF + Java
protected void rulePackage2Schema() { for( EObject pkg : allObjectsOf(IN, "Package") ) { EObject newSchema = createObject(OUT, "Schema"); addToResource(OUT, newSchema);
ruleClass2Table(pkg, newSchema); }}
protected void ruleClass2Table(EObject pkg, EObject schema) { List<EStructuralFeature> classifiers = getMulFeature(pkg, "classifiers"); List<EStructuralFeature> tables = getMulFeature(pkg, "tables");
for( EObject classifier : classifiers ) { EObject newTable = createObject(OUT, "Table");
if ( isKindOf(classifier, "Class") ) { setFeature(newTable, "name", getFeature(classifier, "name")); tables.add(newTable); ... } }}
Recorrer
Crear
Invocar
Framework de soporte
2/12/08 Jesús Sánchez Cuadrado 9
EMF + Java (Valoración)
:-(
:-(
:-)
Muy verboso
Siempre funciona
:-) Modularidad, reutilización, compilación...
Falta de mecanismos de registro de trazas, evitar ciclos, consultas de modelos, etc.
2/12/08 Jesús Sánchez Cuadrado 10
ATL
Atlas Transformation Language
Lenguaje oficial del proyecto Eclipse M2M
http://www.eclipse.org/m2m/atl/
Híbrido
Parte declarativa. Reglas y bindings.
Parte imperativa. Poco desarrollada.
Unidireccional. No incremental.
Modularidad: reglas abstractas, superimposición
Plugin para Eclipse
Editor
Depurador : objeto.debug('salida:')
2/12/08 Jesús Sánchez Cuadrado 11
ATL
rule Class2Table { from c : Class!Class to out : Relational!Table ( name <- c.name, cols <- Sequence {key}->union(c.attributes), key <- Set {key} ), key : Relational!Column ( name <- 'id', type <- Class!DataType.allInstances()->any(e | e.name = 'Integer') )}
rule DataTypeAttribute2Column { from a : Class!Attribute ( a.type.oclIsKindOf(Class!DataType) ) to out : Relational!Column ( name <- a.name, type <- a.type )}
Binding
Origen
Destino
Recorrido implícito
OCL
Filtro
2/12/08 Jesús Sánchez Cuadrado 12
ATL (Valoración)
:-(
:-(
:-)
Necesidad de muchas consultas con OCL Tuple cuando la complejidad crece un poco.
Es el estándar de facto por su simplicidad.
:-) Bastante documentación.
Mal reporte de errores
2/12/08 Jesús Sánchez Cuadrado 13
QVT Relational
Query Views Transformations (OMG)
Estándar OMG
Declarativo. Bidireccional.
Relaciones entre los metamodelos. Patrones.
Sintaxis gráfica de QVT.
Usabilidad – depende de la implementación
Tipado estático. ¿Es suficiente el estándar como guía?
Ningún mecanismo de modularidad.
Implementaciones
MediniQVT. Implementación IKV++
http://projects.ikv.de/qvt
Consistencia y compilación incremental
2/12/08 Jesús Sánchez Cuadrado 14
QVT Relational
top relation PackageToSchema {
pn : String; checkonly domain uml p : UML::Package { name = pn }; enforce domain rdbms s : Relational::Schema { name = pn }; }
Variable
Var. ligada
Patrón
Una relación : declaraciones de dominio.
Un dominio : establece un patrón.
En la ejecución las relaciones se comprueba, y si es necesario se fuerzan.
La clave está en ligar variables.
2/12/08 Jesús Sánchez Cuadrado 15
QVT Relational
relation ClassToTable { cn : String; prefix : String; checkonly domain uml c : UML::Class { package = p : UML::Package { }, name = cn }; enforce domain rdbms t : Relational::Table { schema = s : Relational::Schema { }, name = cn, columns = cl : Relational::Column { name = 'id', type = 'NUMBER' }, key = k : Relational::Key { column = cl : Relational::Column { } } }; when { PackageToSchema(p, s); } where { ClassToPkey(c, k); prefix = cn; AttributeToColumn(c, t, prefix); } }
Parámetro
Precondición“matching”
Postcondición“una llamada”
Navegaciónimplícita
2/12/08 Jesús Sánchez Cuadrado 16
QVT Relacional - Valoración
:-(
:-(
:-)
Abuso del opposite en los patrones, típicamente con variables del when
Paso de parámetros en where
:-) Clausulas en when son consultas de la traza
relation AttributeToColumn { checkonly domain uml c : UML::Class { };
enforce domain rdbms t : Relational::Table { };
primitive domain prefix : String;
where { ComplexAttributeToColumn(c, t, prefix); PrimitiveAttributeToColumn(c, t, prefix); SuperAttributeToColumn(c, t, prefix); }}
¿Es esto declarativo?
¿Cuál se ejecuta?
Son parámetros...
2/12/08 Jesús Sánchez Cuadrado 17
Tefkat
The Engine Formerly Known As Tarzan
DSTC submission for QVT RFP
http://tefkat.sourceforge.net/
Declarativo, basado en
Reglas
Patrones (al contrario que QVT, están separados)
Una transformación satisface las restricciones para crear un modelo destino
Modelo origen: se puede leer
Modelo destino: se establecen restricciones
Tracking extent: se puede leer, se pueden establecer restricciones.
Tracking classes permiten establecer relaciones nombradas entre el origen y el destino
2/12/08 Jesús Sánchez Cuadrado 18
Tefkat
RULE ClassAndTable(C, T) FORALL Class C { name: Name; } MAKE Table T { name: Name; } LINKING ClsToTbl WITH class = C, table = T; RULE MakeColumns WHERE ClassHasAttr(Class, Attr, Name, IsKey) AND ClsToTbl LINKS class = Class, table = Table MAKE Column Col FROM col(C, N) { name: Name; type: Attr.type.name; } SET Table.cols = Col, IF IsKey = true THEN SET Table.pkey = Col ENDIF LINKING AttrToCol WITH class = C, attr = A, col = Col;
CLASS ClsToTbl { Class class; Table table;};CLASS AttrToCol { Class class; Attribute attr; Column col;};
Trackingclasses
“traza explícita”
Crear traza
Restricción sobre traza
Restricción sobre patrón
2/12/08 Jesús Sánchez Cuadrado 19
Tefkat
PATTERN ClassHasAttr(Class, Attr, Name, IsKey) WHERE ClassHasSimpleAttr(Class, Attr, Name, IsKey) OR ClassHasIncludedAttr(Class, Attr, Name, IsKey) OR ClassChildHasAttr(Class, Attr, Name, IsKey);
PATTERN ClassHasSimpleAttr(Class, Attr, Name, IsKey) FORALL Class Class { attrs: Attribute Attr { type: PrimitiveDataType _PT; name: Name; }; } WHERE IsKey = Attr.is_primary;
Patrón
2/12/08 Jesús Sánchez Cuadrado 20
Tefkat
:-(
:-(
:-)
Muy poco eficiente
Tracking classes
:-) Patrones separados de reglas
Dificil hacerlo funcionar
2/12/08 Jesús Sánchez Cuadrado 21
QVT Operacional
Query Views Transformations (OMG)
Estándar OMG
Imperativo. Unidireccional.
Llamadas explícitas a reglas.
Manipulación de la traza: resolve
Usabilidad – depende de la implementación
Tipado estático. ¿Es suficiente el estandar como guía?
Mecanismo de modularidad a nivel de regla.
Implementaciones
SmartQVT.
Proyecto Eclipse M2M.
Open Canarias
2/12/08 Jesús Sánchez Cuadrado 22
QVT Operacional
main() { uml.objectsOfType(Package)->map packageToSchema();}
mapping Package::packageToSchema() : Schema when { self.name.startingWith <> “_” }{ name := self.name; table := self.classifiers->map class2table();}
mapping Class::class2table() : Table{ name := self.name; columns := self.attributes->map attr2col();}
Punto de entrada
Llamada a regla
Filtro
2/12/08 Jesús Sánchez Cuadrado 23
QVT Operacional
:-(
:-(
:-)
Muchas maneras de hacer lo mismo
Intuitivo en principio
:-) Potente para abordar transformaciones complejas
No encuentro implementaciones que funcionen
2/12/08 Jesús Sánchez Cuadrado 24
Epsilon y Viatra
Epsilon
Framework de lenguajes
http://www.eclipse.org/gmt/epsilon/
Interacción con el usuario (integración con GMF)
Utilidad: pequeñas refactorizaciones, scripting
Viatra
Basado en grafos
http://www.eclipse.org/gmt/VIATRA2/
2/12/08 Jesús Sánchez Cuadrado 25
RubyTL
RubyTL
Universidad de Murcia :-)
http://gts.inf.um.es/age
DSL embebido en Ruby
Reutilizamos la infraestructura de Ruby
Híbrido
Parte declarativa. Reglas y bindings.
Parte imperativa. Muy potente. Ej. .map, cadenas, etc.
Concepto novedoso: phases
Usabilidad
Acompañado de otros DSLs
Validación, generación de código, creación de sintaxis concreta, etc.
2/12/08 Jesús Sánchez Cuadrado 26
RubyTL
phase 'class2table' do
top_rule 'class2table' do from ClassM::Class to TableM::Table mapping do |class, table| table.name = class.name table.cols = class.attrs end end
rule 'property2column' do from ClassM::Attribute to TableM::Column filter { |attr| attr.type.is_a? ClassM::PrimitiveType } mapping do |attr, column| column.name = attr.name column.type = attr.type.name
if attr.is_primary column.owner.pkeys << TableM::PKey.new(:col => column) end end end
end
Binding
Código Ruby
Fase
2/12/08 Jesús Sánchez Cuadrado 27
RubyTL
import 'm2m://class2table', :as => 'class2table'
phase 'fkeys' do top_rule 'attribute2fkey' do from ClassM::Attribute to TableM::FKey filter { |attribute| attribute.reference? } mapping do |attribute, fkey| fkey.owner = trace_query(attribute.owner).one(TableM::Table) fkey.references = trace_query(attribute.type).one(TableM::Table) fkey.cols = trace_query(attribute).all(TableM::Column) end endend
scheduling do execute 'class2table' execute 'fkeys'end
Consultarla traza
Constructos: refinement_rule y trace_query
Resolver dependencias “dificiles”
Composición de transformaciones independientes
Importar
2/12/08 Jesús Sánchez Cuadrado 28
RubyTL
:-(
:-(
:-)
No escala bien con modelos grandes.
Muy potente. Usable.
:-) Mecanismo de modularidad. Phases.
Hay que instalar Ruby.
2/12/08 Jesús Sánchez Cuadrado 29
Modularidad
superimposition vs. phases
Sobreescribir reglas
No permite herencia de
reglas
T1 T2 T3
Tm
<<import>>
Transformacionesindependientes
“Comunicación”a través de la
traza
2/12/08 Jesús Sánchez Cuadrado 30
Valoración personal
Faltan implementaciones realmente estables
± estables : ATL, RubyTL, Epsilon
Reutilización muy limitada
Superimposición y phases
Buenas ideas como tracking classes poco desarrolladas
¿Es QVT el lenguaje definitivo?
¿Ha sido QVT perjudicial para la investigación?