PyEmofUCMetamodelo EmofUCJ.M. Drake, P. López Martínez y C. CuevasGrupo de
Ingeniería Software y Tiempo Real (ISTR)
- Universidad
de Cantabria
|
El metametamodelo EmofUC es una extensión del metametamodelo EMOF 2.4 de OMG, en el que se han introducido ligeras modificaciones para simplificar su implementación en el entorno PyEmofUC:
La implementación de las clases Python que
se asocian a los elementos del metametamodelo se generan
dinámicamente en tiempo de ejecución, con las siguientes
características:
Las propiedades de las clases EMOF se formulan en la clase Python como una propiedad Python con el mismo nombre y con el valor por defecto asignado (en caso que lo tenga definido). Sin embargo, como es propio en Phyton, las propiedades toman su tipo cuando se le asigna un valor. Por ello, es responsabilidad de la herramienta que carga o la aplicación que crea un modelo, asegurar que el valor que se asigna es del tipo establecido en el modelo EMOF. Esta información está disponible como parte de la información que proporciona la metaclase asociada.
Las operaciones de las clases EMOF pueden tener declarados parámetros, con nombre, tipo, multiplicidad y valor por defecto. En la implementación Python de las operaciones, se definen los parámetros con las mismas características, salvo el tipo que en el caso de Python se establece en la asignación del valor, esto es, en la invocación. Es de nuevo responsabilidad de la herramienta o aplicación, asignar valores a los parámetros del tipo correcto. Esta información está disponible en la información que proporciona la metaclase asociada.
Al metametamodelo EmofUC
se han incorporado un conjunto de extensiones, utilizando
para ello el mecanismo basado en asociar etiquetas
(instancias de la clase Tag) a los
elementos de los metamodelos, previstos en EMOF.
Las extensiones incorporadas a EmofUC son las
siguientes:
Declaración de tipos primitivos nativos
EMOF (e igualmente EmofUC) permite
declarar tipos primitivos con un nombre asociado. Sin embargo
EMOF, no ofrece mecanismos para especificar las
características del tipo de dato, ni la dependencia por
herencia entre ellos.
En EmofUC, se han declarado 5 tipos de datos básicos
en base a los tipos de datos nativos de Python:
Al estar asociadas las características de
estos tipos de datos a los correspondientes del lenguaje
Python, su características quedan perfectamente especificadas.
Es interesante notar que estos tipos coinciden con los
propuestos en la extensión base que propone OMG para UML. La
única diferencia cualitativa es que OMG propone UnlimitedNatural de enteros sin signo
en vez de PyUnlimitedInteger
como se propone en PyEmofUC que son enteros con signo.
Declaración de tipos primitivos específicos
Se ha considerado de interés introducir en
EmofUC un conjunto de tipos específicos que son
derivados de los tipos primitivos nativos, que permiten
incrementar el detalle en la formalización de la información,
y sobre todo, poder verificar la consistencia de los modelos
de forma previa a su instanciación en el entorno.
Los tipos que se han definido en PyEmofUC, son los que se muestran en la figura previa:
Se han reservado cuatro nombres de etiquetas para la formulación de aspectos relativos a los tipos que se definen en un metamodelo:Cualificación de los tipos primitivos
<ownedType name="URI" xmi:id="emof.URI" xsi:type="emof:PrimitiveType">
<tag name="PT" xmi:id="emof.URI.PT" xsi:type="emof:Tag"
value="emof#emof.PyString"/>
<tag name="RE" xmi:id="emof.URI.RE" xsi:type="emof:Tag"
value="((http://)|(file:///)|(platform:))([a-z]|[A-Z])([a-z]|[A-Z]|[0-9]|/|[.]|_)*"/> </ownedType> |
<ownedType name="Percentage" xmi:id="mast2.Percentage"
xsi:type="emof:PrimitiveType">
<tag name="PT" xmi:id="mast2.Percentage.PT"
xsi:type="emof:Tag"
value="emof#emof.PyReal"/>
<tag name="MAX" xmi:id="mast2.URI.MAX"
xsi:type="emof:Tag"
value="100.0"/>
<tag name="MIN" xmi:id="mast2.URI.MIN"
xsi:type="emof:Tag"
value="0.0"/> </ownedType> |
Declaración de atributos derivados
Una propiedad
derivada es aquella que tiene un valor que se evalua en base
a otros atributos disponibles en la clase en que está
declarado. Una propiedad derivada no se implementa con un
atributo Python en la instancia, sino como una propiedad
Python en la que el método de lectura ejecuta un método
específico en el ámbito de la instancia.
En PyEmofUC se reserva la etiqueta “DPE” para definir el código Python
que implementa el método que evalúa el valor de la propiedad
derivada. En la tabla se muestra como ejemplo la propiedad
derivada isRoot que EMOF define para los elementos
emof.Package. Así mismo, en la siguiente figura se muestra
el código que el entorno PyEmofUC incorpora en la
clase Python que implementa el entorno PyEmofUC a
partir de la información del tag “DPE”.
<ownedType name="Package" xsi:type="emof:Class" xmi:id="emof.Package"
superclass="#emof.NamedElement">
<ownedAttribute name="nestingPackage"
xmi:id="emof.Package.nestingPackage"
xsi:type="emof:Property"
theType="#emof.Package"
opposite="#emof.Package.nestedPackage"/> ……..
<ownedAttribute name="isRoot" xmi:id="emof.Package.isRoot"
xsi:type="emof:Property"
theType="#emof.PyBoolean"
isDerived="True" >
<tag name="DPE" xmi:id="emof.Package.isRoot.DPE"
xsi:type="emof:Tag"
value="return
self.nestingPackage==None"/>
</ownedAttribute> </ownedType> |
Obsérvese que el
sangrado que requiere la sintaxis Python lo introduce de
forma automática el entorno PyEmofUC, pero el
sangrado relativo al código que se introduzca debe ser
introducido con la etiqueta.
Implementación de operaciones de las clases
EMOF prevee
asociar a los elementos del modelo operaciones que describen
aspectos de su comportamiento. EMOF sólo describe los
aspectos de especificación de las cabeceras de los métodos,
esto es, nombre y descripción de los parámetros y del
valor que retorna. Su función es meramente describir la
interfaz pública de los objetos del modelo.
Haciendo uso de tag con nombre reservado “OPE”, en PyEmofUC se permite asociar a las operaciones el código Python que las implementa y que el entorno las genera automáticamente. El método es útil para incorporar el código de pequeñas operaciones de gestión de los objetos del modelo. Para operaciones de negocio mas complejas, se prevee mecanismos de herencia y/o composición que permita asociar a los objetos del modelo código elaborado (y probado) externamente (TODO).
Los tags de
nombre “OPE” se asocian en el
metamodelo a los elementos de tipo emof.Operation, y
contienen en su atributo value el código Python que
implementa la funcionalidad de la operación. El entorno
introduce el sangrado base que requiere la sintaxis de
invocación del código, pero en el código que se incluye en
el tag debe estar el sangrado relativos entre las sentencia
del código introducido.
En la figura se muestra como ejemplo la operación ficha de la clase Familia en el ejemplo FamiliaEmpresa que se describe en este documento.
<ownedType
name="Familia" xmi:id="fam.Familia" xsi:type="emof:Class"
superclass="#fam.Elemento">
<ownedAttribute name="miembro" xmi:id="fam.Familia.miembro"
xsi:type="emof:Property"
theType="#fam.Persona"
isComposite="True"
upper="*" opposite="#fam.Persona.familia"/>
<ownedAttribute name="padre" xmi:id="fam.Familia.padre"
xsi:type="emof:Property"
theType="#fam.Adulto"
lower="0"/>
<ownedAttribute name="madre" xmi:id="fam.Familia.madre"
xsi:type="emof:Property"
theType="#fam.Adulto"
lower="0"/>
<ownedOperation name="hijo" xmi:id="fam.Familia.hijo"
xsi:type="emof:Operation"
theType="#fam.Persona"
lower="0" upper="*">
<tag name="OPE" xmi:id="fam.Familia.hijo.OPE"
xsi:type="emof:Tag"
value="hijos=list(self.miembros);hijos.remove(self.padre)if
self.padre else None;hijos.remove(self.madre) if
self.madre else None; return hijos"/>
</ownedOperation> </ownedType> |
def
hijo(self):
hijos=list(self.miembros);hijos.remove(self.padre)
if self.padre else None; hijos.remove(self.madre) if self.madre else
None; return hijos
A fin de que se pueda generar automáticamente documentación de los modelos se ha reservado los tags con nombre “DOC” para introducir etiquetas con documentación en cada elemento de un modelo.Incorporación de documentación
<ownedType name="Elemento" xmi:id="fam.Elemento" xsi:type="emof:Class"
superclass="emof#emof.Object"
isAbstract="True">
<tag name="DOC" xmi:id="fam.Elemento.DOC"
xsi:type="emof:Tag"
value="Elemento abstracto raiz de otros tipos
de elemento de la familia"/> </ownedType> |