Modelos y metamodelos en AjGenesis

AjGenesis genera código partiendo de un modelo, de libre definición. El modelo se lee desde un archivo .XML (en la versión AjGenesis 0.5) pero también se puede leer desde un archivo de texto. Sobre un modelo sencillo, y sobre la forma de modelo en texto, pueden leer:

Generando Código- Hello World con AjGenesis
Modelo textual para generación de código con AjGenesis

Ha sido una elección inicial de diseño que el modelo sea totalmente libre. El ejemplo más simple de modelo es el que especifica una aplicación Hello World, modelando el mensaje a mostrar:

<Project Company="ajlopez.com">


<Message>Hello, World</Message>


</Project>

Pero de vez en cuando, nos gustaría tener una especificación, algo que indique qué se puede poner o no en un modelo. Esto serviría, para poder construir, por ejemplo, programas que permitan validar el modelo a usar. Es como cuando uno tiene un Schema o DTD que define cómo es un tipo de documento XML, y es usado por distintos utilitarios, para validar y ayudar en la construcción del documento XML final.

Como desde el inicio, el modelo no es XML, sino un concepto abstracto, que por razones de implementación, en la versión actual está en XML, nunca agregué o me apoyé en schemas de XML para definir una estructura al modelo, en ningún ejemplo. Pero siempre quise, en algún momento, agregar, opcionalmente, que se pueda definir el modelo. Y que los mismos formatos que AjGenesis usa, puedan servir para definir esos modelos. La descripción del modelo debería ser otro modelo: es un metamodelo expresado de la misma forma a la que ya estamos habituados en AjGenesis (noten que, históricamente, los DTD siempre algo molestaron en el mundo XML, al no ser ellos mismos XMLs, aunque me apresuro a agregar que hubo otras razones más para reemplazarlos).

Como ejemplo inicial, el modelo de arriba es una instancia de todos los modelos que cumplen con este metamodelo:

<Metamodel Name="SimpleHelloWorld">


    <Types>


        <Type Name="Project">


            <Properties>


                <Property Name="Message"/>


                <Property Name="Company"/>


            </Properties>


        </Type>


    </Types>


</Metamodel>

Cada modelo tiene Types, que se describen en detalle. Si luego, tenemos un modelo de HelloWorld con múltiples mensajes:

<Project>


    <Messages>


        <Message>Hello, World One</Message>


        <Message>Hello, World Two</Message>


        <Message>Hello, World Three</Message>


    </Messages>


</Project>

lo podemos expresar en un metamodelo como:

<Metamodel Name="MultipleHelloWorld">


    <Types>


        <Type Name="Project">


            <Properties>


                <Property Name="Messages" ListOf="String" ItemName="Message"/>


            </Properties>


        </Type>


    </Types>


</Metamodel>

Ahora, tenemos una propiedad que no es simple, sino una lista, de strings. Pero que sus items tienen como nombre a Message (son de la forma <Message>String</Message>).

Tomemos un modelo más complejo. Puedo usar el “clásico” modelo de entidades, de:

Generando aplicaciones con AjGenesis

El proyecto más simple es AjFirstExample (dos entidades simples):

<Project>


    <Name>AjFirstExample</Name>


    <Description>First Example using AjGenesis</Description>


    <Prefix>AjFE</Prefix>


    <Domain>com.ajlopez</Domain>


    <CompanyName>ajlopez</CompanyName>


    <Model>


        <Entities>


            <Entity Source="Entities/Customer.xml"/>


            <Entity Source="Entities/Supplier.xml"/>


        </Entities>


        <Lists>


            <List Entity="Customer"/>


            <List Entity="Supplier"/>


        </Lists>


        <Forms>


            <Form Entity="Customer"/>


            <Form Entity="Supplier"/>


        </Forms>


        <Views>


            <View Entity="Customer"/>


            <View Entity="Supplier"/>


        </Views>


    </Model>


</Project>

Como ejemplo, recordemos la entidad Customer:

¿Cómo podemos representar esto en un metamodelo? De esta forma:
 
<Metamodel Name="EntityModel">


    <Types>


        <Type Name="Project">


            <Properties>


                <Property Name="Name"/>


                <Property Name="Description"/>


                <Property Name="Prefix"/>


                <Property Name="Domain"/>


                <Property Name="CompanyName"/>


                <Property Name="Model" Type="Model"/>


            </Properties>


        </Type>


        <Type Name="Model">


            <Properties>


                <Property Name="Entities" ListOf="Entity"/>


                <Property Name="Lists" ListOf="List"/>


                <Property Name="Views" ListOf="View"/>


                <Property Name="Forms" ListOf="Form"/>


            </Properties>


        </Type>


        <Type Name="Entity">


            <Properties>


                <Property Name="Name" />


                <Property Name="SetName" />


                <Property Name="Description" />


                <Property Name="Descriptor" />


                <Property Name="SetDescriptor" />


                <Property Name="SqlTable" />


                <Property Name="Properties" ListOf="Property" />


            </Properties>


        </Type>


        <Type Name="Property">


            <Properties>


                <Property Name="Name" />


                <Property Name="Type" />


                <Property Name="SqlType" />


            </Properties>


        </Type>


        <Type Name="List"/>


        <Type Name="View"/>


        <Type Name="Form"/>


    </Types>


</Metamodel>

(Faltaría completar los tipos Property, List, View, Form). Y la prueba de fuego, es que el propio metamodelo pueda expresarse como metamodelo:

<Metamodel Name="Metamodel">


    <Types>


        <Type Name="Metamodel">


            <Properties>


                <Property Name="Name"/>


                <Property Name="Types" ListOf="Type"/>


            </Properties>


        </Type>


        <Type Name="Type">


            <Properties>


                <Property Name="Name"/>


                <Property Name="Properties" ListOf="Property"/>


            </Properties>


        </Type>


        <Type Name="Property">


            <Properties>


                <Property Name="Name" />


                <Property Name="ListOf" Reference="Type" />


            </Properties>


        </Type>


    </Types>


</Metamodel>



¿Y para qué tanto trabajo? Para poder usar esa información para validar el modelo, es una razón. Pero también, recordemos, AjGenesis genera código. Podríamos generar el código de un diseñador, de un modelador web o gráfico, que permita:



- Leer y grabar el modelo
- Ver sus datos (gráficamente, o en formularios)
- Ingresar su contenido





Por ejemplo, podríamos armar un programa .NET WinForm, que muestre un árbol a la izquierda con la estructura de nuestro modelo (ej. Entidades) y que permita agregar las ramas de ese árbol. Podemos generar las clases tipadas que representen ese modelo en memoria. Y los códigos de los serializadores del modelo en XML  o en texto o en lo que elijamos. También se podría leer el metamodelo desde un programa genérico, y que éste maneje el mostrado y el ingreso de datos del modelo, dinámicamente, en runtime:





Pero todo esto no es necesario para trabajar hoy por hoy con AjGenesis. Quería mencionarlo, porque lo tengo en suspenso desde hace unos años como idea. No es un tema prioritario por ahora, lo que más se necesita es documentación, ejemplos mejorados y ejemplos con nuevas tecnologías.



Nos leemos!



Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

This entry was posted in 2643, 6145. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>