Proyecto AutoGSA
Sesión 6
Fornax Y AndroMDA
Herramientas para la generación de código
Fornax
Herramientas para la generación de código
Indice




Introducción
Proyectos de soporte de la plataforma
Componentes de la plataforma
Cartuchos


UML2
Sculptor

Primer proyecto




Archetypes












Dominio ejemplo
Creación del proyecto
Modificación del Negocio
DSL del Negocio
Modificación de la Vista
DSL de la Vista
Diseño interno del cartucho Sculptor


Configuración de los proyectos maven
Modificación de la capa de negocio
Modificación de la cava de la vista
Generación y ejecución
Modificaciones tecnológicas
DSL del Negocio y de la GUI


Instalación y configuración
Creación de un proyecto
Completando pruebas (test) de Junit
Propiedades del Generador
Modelo del Dominio
Modelo de la Interfaz
Herramientas para la generación de código
Fornax

La plataforma Fornax es una plataforma de desarrollo con
herramientas enmarcadas en el Desarrollo de Software Dirigido
por Modelos (DSDM)

Las herramientas son: cartuchos, transformadores,
generadores de código, etc…

Fornax es una plataforma abierta para desarrollar
componentes y herramientas en el contexto del DSDM. Esta
basada en el framework openArchitectureWare (que a su vez
ofrece numerosos componentes para el DSDM).
Herramientas para la generación de código
Proyectos de soporte de la plataforma

La plataforma esta soportada por diferentes herramientas
OpenSource como: Subversion, Maven ó Eclipse.
Herramientas para la generación de código

Subversion
Subversion es un SCM (SourceControlManagement). Todos los fuentes
se almacenan asegurando la integridad del proyecto.

Eclipse
Una de las mejores plataformas de desarrollo.Ofrece una IDE potente
que simplifica el procesode desarrollo.

Maven2
Usado como repositorio de recursos y dependencias y como gestor en la
construcción de los proyectos.

Confluence
Plataforma wiki para gestionar la colaboración ente los proyectos de la
plataforma Fornax.

JIRA
Track para el desarrollo de proyectos. Seguimient de tareas pendientes
resueltas para los proyectos de la plataforma.
Herramientas para la generación de código


openArchitectureWare (oAW)
Uno de los frameworks para arquitecturas generativas más potentes.
Mylar
Interfaz de usuario para Eclipse que permite una eficiente integración
de Subversion y JIRA en el desarrollo de proyectos.
Herramientas para la generación de código
Componentes de la plataforma

Elementos que conforman la plataforma Fornax

Archetypes
Son plugins Maven2 que permiten la creación de un proyecto y su
estructura, incluyendo los ficheros necesarios según la
arquitectura destino configurada.

Cartuchos de openArchitectureWare
Componentes usados en Fornax para la generación de código en
una determinada arquitectura destino

Repositorio de Maven2
Administra los artefactos producidos y necesarios en caulquier
proyecto de la plataforma.
Herramientas para la generación de código
Proyectos de la Plataforma

Fornax-Internals
Core de la plataforma. Subproyectos internos y transparentes al
desarrollo con Fornax.

Cartuchos
Cartuchos que proveen de los elementos necesarios (plantillas,
extensiones, …) para la generación de código en diferentes
frameworks destino

Transformadres
Basado en el mecanismo d e transformación de oAW, permite el
desarrollo interno y necesario de transformaciones m2m.

Herramientas de soporte
Herramientas de soporte específico, como el plugin de eclipse para
el uso de proyectos Maven2.
Herramientas para la generación de código
Herramientas para la generación de código

Cartridges
La plataforma Fornax actualmente ofrece 2 tipos de cartuchos:

Sculptor


Ofrece un proceso de desarrollo software generativo, basado en el
uso de lenguajes específicos del dominio.
UML2


Permite la generación de código desde modelos UML2 (similar a
AndroMDA)
Cartuchos disponibles:







EJB 3 (CEJ)
EJB2 (CEB)
Grails (CGR)
Hibernate (CHB)
Java Server Faces (CJF)
JavaBasic (CJB)
Spring2 (CSP)
Herramientas para la generación de código
Cartuchos UML2



Cada cartucho en UML2 requiere un conjunto de modelos
estruturales (usando diagramas de clases y perfiles propios del
cartucho) y, dependiendo del cartucho utilizado, un conjunto de
modelos de comportamiento (representados mediante
diagramas de actividades)
Modelos UML2 de entrada en XMI
Ejemplo: Cartucho de Hibernate
Herramientas para la generación de código
Estructura del proyecto Hibernate
fornax-cartridges-uml2-hibernate-parent-1.X.X

lib
...
src
generated
main
java
resources
example-model.mdzip
example-model.uml
Persistence_Profile.mdzip
Persistence.profile.uml
workflow.oaw
workflow.properties
hibernateCartridge.properties
Herramientas para la generación de código

Después de generar (usamos Ant)

Ficheros demapeo y configuración de Hibernate en
‘src/generated/resources’
Herramientas para la generación de código

Los POJOS se generan en ‘src/generated/java’ y ’src/main/java’
Herramientas para la generación de código

Ejemplo: Cartucho JSF
Herramientas para la generación de código

Utiliza además los cartuchos de Spring e Hibernate

El estereotipo <<BackingBean>> genera una página que
provee la funcionalidad para gestionar las entidades
necesarias en el servicio dependiente de la entidad (en la
imagen se muestra una página con 3 pestañas ara cada
entidad y servicio indicados e el modelo anterior).
Herramientas para la generación de código

Mediante Diagramas de Actividades se puede indicar el flujo de
navegación entre páginas (estereotipo <<Page>>) así como la
ejecución de acciones en páginas.
Herramientas para la generación de código
Cartucho Sculptor



Versión 1.5.0. Fecha salida: 1 de Febrero de 2009.
Se trata de una plataforma sencilla pero potente para la
generación de código.
Permite centrarse en el dominio o negocio y no en los detalles
técnicos

Usa los conceptos del DDD (Diseño Dirigido por Dominios):
Service, Module, Entity, Value Object, Repository...

Sculptor ofrece 2 DSL textuales para código en frameworks
como: Spring Framework, Spring Web
Flow, JSF, RCP, Hibernate y Java EE.

Para la generación de código se basa en oAW.
Herramientas para la generación de código
Resumen de carácterísticas

Basado en oAW 4.3.1

Define un DSL para la lógica de negocio y otro DSL para la
GUI

Soporte de GUI para Rich Client y para Web
Herramientas para la generación de código
Primer proyecto: Instalación

JDK


Instalar JDK 6 o JDK 5.
Maven

Usado en la generación de código fuente y en la construcción de
los proyectos.


1. Instalar Maven2 .
2. Definir JAVA_HOME


set JAVA_HOME=c:\devtools\jdk1.6.0_03
set MAVEN_OPTS=-Xms128m -Xmx1024m
Herramientas para la generación de código

Eclipse y Plugins

Eclipse 3.4 Ganymede (Eclipse IDE for Java EE Developers)
 oAW 4.3.1 http://www.openarchitectureware.org/updatesite/milestone/site.xml
Herramientas para la generación de código

Sculptor Plugins: http://fornax-platform.org/updatesite/

Sculptor Rich Client Feature 1.5.0. (opcional)

Subversive: http://www.eclipse.org/subversive/downloads.php
(opcional)

Configuración de Eclipse


Añadir en 'Classpath Variable' de Eclipse: M2_REPO=<directorio_del_reposiorio>
(Window -> Preferences -> Java -> Build Path -> Classpath Variables)
 Generalmente: ‘.m2/repository’ en el directorio home

Añadir 'String Substitution Variable' en Eclipse para
MAVEN_EXEC=<MAVEN_HOME>/bin/mvn.bat
Instalar Plugin Maven2 (opcional)

http://m2eclipse.codehaus.org/
Con el updatesite ‘http://m2eclipse.sonatype.org/update/’
Herramientas para la generación de código
Primer proyecto: Creación de un proyecto

Crear un proyecto para Sculptor

Configurar la estructura del proyecto para maven y eclipse:

Crear proyecto maven (pom y estructura)
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create
-DarchetypeGroupId=org.fornax.cartridges
-DarchetypeArtifactId=fornax-cartridges-sculptor-archetype-standalone -DarchetypeVersion=1.6.0SNAPSHOT
-DremoteRepositories=http://www.fornax-platform.org/archiva/repository/snapshots/
-DgroupId=org.helloworld -DartifactId=helloworld

Crear proyecto Eclipse
Ejecutar mvn eclipse:eclipse en el nuevo directorio para crear el
proyecto Eclipse con las mismas dependencias que el .pom

Abrir Eclipse e importar el proyecto.
Herramientas para la generación de código

Modificar el modelo del dominio a través del archivo: model.design en la carpeta
src/main/resources/
model.design
Application Universe {
basePackage=org.helloworld
Module milkyway {
Service PlanetService {
String sayHello(String planetName);
protected findByExample => PlanetRepository.findByExample;
}
Entity Planet {
String name key;
String message;
Repository PlanetRepository {
findByExample;
}
}
}
}
Herramientas para la generación de código

Ejecutar mvn clean install para generar el código y construir el
proyecto (inicialmente las pruebas en Junit fallarán).

El proyecto generado tiene 3 tipos de paquetes:



src : solo generados la primera vez (se borran con clean).
Permiten edición manual. Ficheros fuentes principales (java y
resources).
test: solo generados la primera vez (se borran con clean).
Permiten edición manual. Ficheros de pruebas para JUnit.
generated: se borran y se crean en cada regeneración. No tocar
manualmente puesto que se pierden los cambios.
Herramientas para la generación de código
Herramientas para la generación de código
Herramientas para la generación de código
Herramientas para la generación de código

Validando con las pruebas de Junit

Ejecutar PlanetServiceTest mediante Junit => error.

testSayHello:
public void testSayHello() throws Exception {
String greeting = planetService.sayHello(getServiceContext(),
"Earth");
assertEquals("Hello from Earth", greeting);
}
Herramientas para la generación de código

Por defecto se usa HSQLDB en memoria (no BBDD externa) para las
pruebas JUnit. Añadir datos:
‘src/test/resources/dbunit/PlanetServiceTest.xml’
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<PLANET id="1" name="Earth" message="Hello from Earth"
LASTUPDATED="2006-12-08" LASTUPDATEDBY="dbunit"
version="1" />
<PLANET id="2" name="Mars" message="Hello from Mars"
LASTUPDATED="2006-12-08" LASTUPDATEDBY="dbunit"
version="1" />
</dataset>
Herramientas para la generación de código

Implementar el método sayHello de PlanetServiceImpl:
public String sayHello(ServiceContext ctx, String planetName) {
Planet planetExample = new Planet(planetName);
List<Planet> foundPlanets = findByExample(ctx, planetExample);
Planet planet = foundPlanets.get(0);
return planet.getMessage();
}

Validación correcta.
Herramientas para la generación de código

Nuevo método en el test para generar un error de datos en la
validación:
public void testSayHelloError() throws Exception {
try {
planetService.sayHello(getServiceContext(), "pluto");
fail("Excpected PlanetNotFoundException");
} catch (PlanetNotFoundException e) {
// as expected
}
}

Necesario añadir nuevo concepto al
modelo:PlanetNotFoundException en model.design.
String sayHello(String planetName) throws
PlanetNotFoundException;

8. Regenerar proyecto:

mvn -Dfornax.generator.force.execution=true generate-sources
Herramientas para la generación de código

Añadir ‘throws PlanetNotFoundException’ en el método de la la clase
PlanetServiceImpl.sayHello.

Modificar el método sayHello:
public String sayHello(ServiceContext ctx, String planetName)
throws PlanetNotFoundException {
Planet planetExample = new Planet(planetName);
List<Planet> foundPlanets = findByExample(ctx, planetExample);
if (foundPlanets.isEmpty()) {
throw new PlanetNotFoundException("Didn't find any planet named " + planetName);
}
Planet planet = foundPlanets.get(0);
return planet.getMessage();
}

Ejecutar: mvn clean install para reconstruir el proyecto (¿Por qué es necesario?¿no es
suficiente con regenerar?)
mvn -o -npu instal (-o == offline, -npu == no plugin upate agilizan la reconstrucción evitando
descargas en linea innecesarias).

Ejecutar: mvn -Dfornax.generator.force.execution=true -o -npu generate-sources para
regenerar el proyecto.
Herramientas para la generación de código
Archetypes


Ejemplo de aplicación Java2EE usando los archetypes de
Sculptor. Se obtienen 4 proyectos:

sculptor-helloworld-parent : proyecto padre de los otros 2
proyectos.

sculptor-helloworld: Proyecto EJB con la mplementación d ela
capa de negocio

sculptor-helloworld-web: Proyecto web con la GUI orientada a
aplicaciones CRUD.

sculptor-helloworld-ear: Desplegable de la aplicación
Nota: omitiremos el uso de EJB y EAR.
Herramientas para la generación de código
Configuración de los proyecto maven

Creacion de los proyectos maven y eclipse en el mismo
script: sculptor-archetypes.cmd.
set MVN_HOME=C:\devtools\Maven-2.0.8
set JAVA_HOME=C:\devtools\jdk1.6.0_03
set path=%MVN_HOME%\bin;%JAVA_HOME%\bin
set PACKAGE=%1
set SYS_NAME=%2
call mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create DarchetypeGroupId=org.fornax.cartridges -DarchetypeArtifactId=fornaxcartridges-sculptor-archetype-parent -DarchetypeVersion=1.6.0-SNAPSHOT DremoteRepositories=http://www.fornax-platform.org/archiva/repository/snapshots/
-DgroupId=%PACKAGE% -DartifactId=%SYS_NAME%-parent
call mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create DarchetypeGroupId=org.fornax.cartridges -DarchetypeArtifactId=fornaxcartridges-sculptor-archetype -DarchetypeVersion=1.6.0-SNAPSHOT DremoteRepositories=http://www.fornax-platform.org/archiva/repository/snapshots/
-DgroupId=%PACKAGE% -DartifactId=%SYS_NAME%
Herramientas para la generación de código
call mvn org.apache.maven.plugins:maven-archetype-plugin:1.0alpha-7:create -DarchetypeGroupId=org.fornax.cartridges DarchetypeArtifactId=fornax-cartridges-sculptor-archetype-jsf DarchetypeVersion=1.6.0-SNAPSHOT DremoteRepositories=http://www.fornaxplatform.org/archiva/repository/snapshots/ DgroupId=%PACKAGE% -DartifactId=%SYS_NAME%-web
pause
cd %SYS_NAME%-parent
call mvn install
pause
call mvn -DdownloadSources=false eclipse:eclipse
cd ..
Herramientas para la generación de código

La capa de presentación puede implementarse como una GUI
de una aplicación RCP o como una interfaz web

La interfaz web puede ser implementada a su vez como:
1. Spring webflow con JSF y Facelets
2. Spring webflow con JSP (solo)


Scripts para JSF.
Para JSP usar el cartucho generador:fornax-cartridgessculptor-archetype-web

Invocar el script: sculptor-archetypes org.helloworld helloworld
Herramientas para la generación de código


Abrir Eclipse e importar los 3 proyectos.
Modificar la capa de negocio:
model.design
Application Universe {
basePackage=org.helloworld
Genera operaciones CRUD y
PlanetRepository + PlanetService
Module milkyway {
Entity Planet {
scaffold
String name key;
String message;
Integer diameter nullable;
Integer population nullable;
- Set<@Moon> moons opposite planet;
}
Entity Moon {
not aggregateRoot // belongs to Planet Aggregate
String name key;
Integer diameter nullable;
- @Planet planet opposite moons;
}
}
}
Herramientas para la generación de código
Modificación de la capa de la vista

model.guidesign en el proyecto web
import 'platform:/resource/helloworld/src/main/resources/model.design' gui
UniverseWeb for Universe { }

Construir la aplicación: mvn -Dmaven.test.skip=true clean
install desde el proyecto parent (omitir validación).

Actualizar proyectos en Eclipse

Ejecutar en el servidor Jetty (interno) haciendo uso de maven:
mvn jetty:run en el helloworld-web

http://localhost:8080/helloworld-web
Herramientas para la generación de código
Modificaciones tecnológicas
Usar JBoss AS
 Instalar JBoss AS 4.2.2.GA
 Problemas de versión con Hibernate:
Reemplazar hibernate3.jar de server/default/lib por hibernate3.2.5.ga.jar del repositorio maven
(repository/org/hibernate/hibernate/3.2.5.ga/hibernate-3.2.5.ga.jar)
 Copiar
repository/opt/repository/net/sf/ehcache/ehcache/1.2.3/ehcache1.2.3.jar a toserver/default/lib.

Configurar Jboss en el proyecto

sculptor-generator.properties de helloworld:
deployment.applicationServer=JBoss



Reconstruir proyecto: mvn -Dmaven.test.skip=true clean install desde
el parent
Copiar war al servidor Jboss (por ejemplo: server/default/deploy/)
http://localhost:8080/helloworld-web
Herramientas para la generación de código
Usar base de datos MySQL

sculptor-generator.properties de helloworld.
db.product=mysql

Reconstruir mvn clean install from helloworld-parent


Crear esquema universe en MySQL
Crear tablas: helloworld/src/generated/resources/dbschema/Universe_ddl.sql

Crear datasource en Jboss: server/default/deploy/universe-mysql-ds.xml
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>jdbc/UniverseDS</jndi-name>
<connection-url>jdbc:mysql://localhost/universe</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>root</password>
</local-tx-datasource>
</datasources>

6. Copiar mysql-connector jar a JBoss (server/default/lib/)
‘repository\mysql\mysql-connector-java\3.1.14\mysql-connector-java-3.1.14.jar’
Herramientas para la generación de código

Mas modificaciones:

Despliegue en formato EAR con EJB en lugar de WAR
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create DarchetypeGroupId=org.fornax.cartridges -DarchetypeArtifactId=fornaxcartridges-sculptor-archetype-ear -DarchetypeVersion=1.6.0-SNAPSHOT DremoteRepositories=http://www.fornaxplatform.org/archiva/repository/snapshots/ -DgroupId=org.helloworld DartifactId=helloworld-ear

Usar EJB 2.1

sculptor-generator.properties:
ejb.version=2.1
Herramientas para la generación de código
DSL del Negocio y de la GUI

Ejemplo: Library
Herramientas para la generación de código

mvn org.apache.maven.plugins:maven-archetype-plugin:1.0alpha-7:create -DarchetypeGroupId=org.fornax.cartridges
-DarchetypeArtifactId=fornax-cartridges-sculptor-archetypestandalone -DarchetypeVersion=1.6.0-SNAPSHOT
-DremoteRepositories=http://www.fornaxplatform.org/archiva/repository/snapshots/
-DgroupId=org.library -DartifactId=library


mvn eclipse:eclipse
Importar en Eclipse
Herramientas para la generación de código
Modificación del negocio
model.design
Application Library {
basePackage = org.library
Module media {
Service LibraryService {
findLibraryByName => LibraryRepository.findLibraryByName;
findMediaByName => MediaRepository.findMediaByName;
findMediaByCharacter =>
MediaRepository.findMediaByCharacter;
findPersonByName => PersonService.findPersonByName;
}
Entity Library {
scaffold
String name key
- Set<@PhysicalMedia> media <-> library
Service MediaService {
findAll => MediaRepository.findAll;
}
abstract Entity Media {
String title !changeable
- Set<@PhysicalMedia> physicalMedia inverse <-> media
- Set<@Engagement> engagements <-> media
- Set<@MediaCharacter> mediaCharacters <-> existsInMedia
Repository MediaRepository {
> @MediaCharacterRepository
int getNumberOfMovies(Long libraryId) => AccessObject;
List<@Media> findMediaByCharacter(Long libraryId, String
characterName);
findById;
save;
findAll;
findByQuery;
protected findByKeys(Set<String> keys, String
keyPropertyName, Class persistentClass);
List<@Media> findMediaByName(Long libraryId, String name);
Map<String, @Movie> findMovieByUrlIMDB(Set<String>
keys);
}
Repository LibraryRepository {
findByQuery;
@Library findLibraryByName(String name) throws
LibraryNotFoundException;
}
}
Entity PhysicalMedia {
scaffold
String status length="3"
String location
- @Library library nullable <-> media
- Set<@Media> media <-> physicalMedia
}
}
Entity Book extends @Media {
!auditable
String isbn key length="20"
}
Herramientas para la generación de código
Entity Movie extends @Media {
!auditable
String urlIMDB key
Integer playLength
- @Genre category nullable
}
enum Genre {
ACTION,
COMEDY,
DRAMA,
SCI_FI
}
Module person {
Service PersonService {
findPersonByName => PersonRepository.findPersonByName;
}
Entity Person {
scaffold
Date birthDate
- @Gender sex !changeable
- @Ssn ssn key
- @PersonName name
Repository PersonRepository {
List<@Person> findPersonByName(String name) =>
AccessObject;
save;
save(Collection<@Person> entities);
findByQuery;
findByExample;
findByKeys;
}
ValueObject Engagement {
String role
- @Person person
- @Media media <-> engagements
}
Service MediaCharacterService {
findAll => MediaCharacterRepository.findAll;
}
ValueObject MediaCharacter {
String name !changeable
- Set<@Person> playedBy
- Set<@Media> existsInMedia <-> mediaCharacters
}
BasicType Ssn {
String number key length="20"
String country key length="2"
}
BasicType PersonName {
String first
String last
}
enum Gender {
FEMALE("F"),
MALE("M")
}
Repository MediaCharacterRepository {
findByQuery;
findAll;
}
}
}
}
}
Herramientas para la generación de código
DSL del Negocio

Analizar conceptos en el DSL del Negocio

Domain Objects


Entity



3 tipos de Domain Objects: Entity, ValueObject, BasicType
Categoría de objetos con identidad (entidades).
Con estado, continuidad e identidad en un sistema.
ValueObject

Cuando se necesitan ciertos atributos de un element de dominio,
pero no interesa el objeto como identidad (no interesa saber a que
ejemplar corresponder los valores de los atributos, solo interesan
los atributos).Un objeto que se usa para describir ciertos aspectos
de un dominio,y que no tiene identidad.
Herramientas para la generación de código

BasicType

Representa tipos basicos y fundamentales (una moneda, un rango
de valores, etc…)

BasicType es un ValueObject que se guarda en la misma tabla
que el objeto del domino que lo referencia (Component de
Hibernate).
Herramientas para la generación de código

Aggregate


Un agregado es un grupo de objetos asociados que son
considerados como una unidad. Se delimitan los objetos de dentro
con respecto a los de fuera. Cada agregado tiene una raíz que es
una Entity (único objeto accesible desde fuera). La raíz puede
referenciar a cualquier objeto agregado y los objetos agregados
se puede referenciar unos a otros, pero un objeto externo solo
puede referencia al objeto raíz (no a los agregados)
En Sculptor toda Entity es por defecto una raiz agregada, pero
se puede usar !aggregateRoot para indicar lo contrario.
Herramientas para la generación de código

Repository


Service


Abstrae de los detalle técnicos de acceso a bases de datos.
Encapsula la lógica necesaria para recuperar las referencia a
objetos. Los Domain objetct no entienden sobre la infraestructura
de acceso a datos, simplemente usan el repositorio.
Capa de servicios sobre la capa del modelo. Ofrece una interfaz
bien definida con un conjunto de servicios para los clientes.
Module



Permite organizar conceptos y tareas relacionados con el fin de
simplificar la comprensión del problema. Además es importante
mantener los principios de alta cohesión y bajo acoplamiento.
Sculptor los implementa como paquetes Java.
No se permiten referencias circulares entre módulos.
Herramientas para la generación de código

Como generar Domain Objects

Código generado en clase base generada
 Código manual en subclase donde añadir métodos para implementar el
comportamiento del Domain Object (no se sobreescribe)

Atributos y Referencias


Los Domain Objects pueden tener atributos simples y referencias a otros Domain
Objects o enums.
Primitive types o cualquier clase Java puede ser usado como tipo de
atributos.






String
Integer (int)
Long (long)
Boolean (boolean)
Date
DateTime, Timestamp
Herramientas para la generación de código



Las declaraciones de referencias empiezan por -.
En otros sitios podemos ver los nombres comenzando con @ para
indicar que la declaración se refiere a un Domain Object.
En relaciones many-to-one o many-to-many se usa una colección
como tipo de la referencia. Las asociaciones direccionales se
representan con: <->
Entity PhysicalMedia {
String status
String location
- @Library library <-> media
- Set<@Media> media <-> physicalMedia
}

Tipos de colecciones: Set (desordenado), List (ordenado usando una
columna como indice), Bag (ordenado usando orderby)
Herramientas para la generación de código

Key

Atributos identificadores (si en una dentidad no se definen, Sculptor
genera uno mediante UUID)

Si es compuesta, los atributos conforman una clase nueva (por ejemplo con
un objeto BasicType). Este objeto clave debe tener al menos un atributo
marcado como clave.
Entity Person {
Integer age
- @Ssn ssn key
- @PersonName name
}
BasicType Ssn {
String number key
String country key
}

Los objetos ersistentes (Entitiies y Valu Objects) deben tener un atributo
id, que coincide con la pk de bbdd..
Herramientas para la generación de código

Changeable

Atributos y Referencias cambiables. Por defecto, las entidades son
cambiables, y los Value Objects y Basictypes no (necesario definirlos
como !immutable para que sean modificables). Las claves nunca son
modificables.
ValueObject ChangeableColor {
!immutable
String name !changeable;
int red;
int green;
int blue;
}

Los atributos y referencias definidas como !changeable se incluyen en el
constructor y no disponen de metodos setter publicos..
Herramientas para la generación de código

Required

Un complemento a changeable. Se incluye en el constructor y
dispone de setter.
ValueObject ChangeableColor {
!immutable
String name !changeable;
int red required;
int green required;
int blue required;
}
Herramientas para la generación de código

Nullable


Atributo puede ser nulo o no
Auditable

Actualización automática de las propiedades: 'lastUpdated',
'lastUpdatedBy', 'createdDate' y 'createdBy'. Por defecto una
entidad es auditable.
Entity Book extends Media {
!auditable
String isbn key
}
Herramientas para la generación de código


Aggregate
Cualquier entidad por defecto es raiz de agregado. Pero a veces una entidad
forma parte de un agregado y no es raiz de ninguna otra (dependencias)
Entity PurchaseOrder {
- @Money approvedLimit
- List<@PurchaseOrderLineItem> items
}
Entity PurchaseOrderLineItem {
!aggregateRoot
Integer quantity
- @Money price
- @Part part
}
Entity Part {
- @Money price
}
Herramientas para la generación de código

Non-persistent ValueObject

Solo para Value Object
Service PersonService {
Set<@Person> findPersonsMatching(@PersonCriteria personCriteria);
}
ValueObject PersonCriteria {
!persistent
String name
String country
- @AgeInterval ageBetween
}
BasicType AgeInterval {
Integer minAge
Integer maxAge
}
Herramientas para la generación de código

Enumerados
enum Genre {
ACTION,
COMEDY,
DRAMA,
SCI_FI
}
Asociar un valor clave al enumerado:
enum Gender {
String code key
FEMALE("F"),
MALE("M")
}
Definicion implcita mediante un atributo ‘value’:
enum Gender {
FEMALE("F"),
MALE("M")
}
enum WindSpeed {
int beaufortNumber key;
double minMps;
double maxMps;
CALM(1, "0", "0.2"),
STORM(10, "24.5", "28.4"),
HURRICAN(12, "32.7", "40.8");
}
Herramientas para la generación de código

Nombre de los elementos de la Base de Datos:
Entity PhysicalMedia {
databaseTable="PHMED"
String status databaseColumn="STAT"
String location databaseColumn="LOC"
- @Library library databaseColumn="LIB" <-> media
- Set<@Media> media databaseColumn="MED" <->
physicalMedia
}
Herramientas para la generación de código

Otros aspectos de los atributos:

nullable, index, databaseColumn, databaseType y length
Entity Person {
String ssn key length="15"
String country key databaseType="CHAR" length="2"
Integer age nullable
- @PersonName name
}
BasicType PersonName {
String first index
String last index
}
Herramientas para la generación de código

Diagrama del modelo del dominio

Diagrama visaulizable con Graphviz
Sculptor genera un fichero .dot textual que se utiliza para
generar el diagrama gráfico.
Herramientas para la generación de código




Generar Services
En el DSL, una operación de un Service es como un método ordinario
Java que devuelve un tipo, con parámetros y que lanza una
excepción. No es necesario declarar la visibilidad por que esta es
pública.
List<@Movie> findBestMovies(Long libraryId);
Las colecciones tienen la sintaxis genérica de Java:

Set
 List
 Map
 Collection

Delegar una operación en un repositorio u otro servicio. Los
parámetros y el tipo de retorno se copian.

findLibraryByName => LibraryRepository.findLibraryByName;
Herramientas para la generación de código

El código que se genera es:








Interface. P.ej.: LibraryService
Implementation class, P.ej.:. LibraryServiceImpl
Clase base para la implementación, P.ej.:. LibraryServiceImplBase
Stateless session EJB
Proxy de cliente en EJB
Test class, P.ej.:. LibraryServiceTest
Clase Base para el test, P.ej.: LibraryServiceTestBase
La separación del código generado y escrito viene con la clase base
generada y su subclase que es modificada manualmente.
Herramientas para la generación de código


Generic Access Objects
Sculptor proporciona una implementación genérica para las
siguientes operaciones de cualquier Domain Object:









findById
findAll
findByExample
findByQuery
findByCriteria
findByKeys
save
merge
delete
Herramientas para la generación de código

Para usar un Generic Acces Object solo hay que indicarlo en el
Repository:
Repository LibraryRepository {
findById;
save;
findByQuery;
}
Herramientas para la generación de código

Custom Access Objects
Repository MediaRepository {
int getNumberOfMovies(Long libraryId) => AccessObject;
...
}

La lógica de negocio en la correspondiente clase xxxAccessImpl:
public class GetNumberOfMoviesAccessImpl extends
GetNumberOfMoviesAccessImplBase {
public void performExecute() {
DetachedCriteria criteria = DetachedCriteria.forClass(Movie.class);
criteria.setProjection(Projections.rowCount());
List result = getHibernateTemplate().findByCriteria(criteria);
Number count = (Number) result.get(0);
setResult(count.intValue());
}
}
Herramientas para la generación de código

Scaffold
Entity Person {
scaffold
String ssn key
String name
}
Da lugar a….
Service PersonService {
findById => PersonRepository.findById;
findAll => PersonRepository.findAll;
save => PersonRepository.save;
delete => PersonRepository.delete;
}
Entity Person {
String ssn key
String name
Repository PersonRepository {
findById;
findAll;
save;
delete;
}
}

El Repository y el Service se añaden automaticamente.
Herramientas para la generación de código

Dividir el modelo en varios archivos:
model.design
import "platform:/resource/library/src/main/resources/model-person.design"
Application Library {
basePackage = org.library
Module media {
// as usual ...
}
}
model-person.design
ApplicationPart PersonPart {
Module person {
// as usual ...
}
Herramientas para la generación de código
Modificacion de la Vista

Generar y configurar una interfaz web.

Ejemplo de partida:
model.design
Application Universe {
basePackage=org.helloworld
Module milkyway {
Service PlanetService {
String sayHello(String planetName);
protected findByExample => PlanetRepository.findByExample;
}
Entity Planet {
String name key;
String message;
Repository PlanetRepository {
findByExample;
}
}
}
}
Herramientas para la generación de código

2 diferentes implementaciones:

Spring webflow con JSP
 Spring webflow con JSF y Facelets

Completar las pruebas de validacion de JUnit sobre el ejemplo:


Ejecutar CreatePlanetTest como JUnit Test => error
Completar:
@Override
protected void populateFormSuccess(MockParameterMap parameters) {
parameters.put("name", "Earth");
parameters.put("message", "Hello from Earth");
}
@Override
protected void populateFormError(MockParameterMap parameters) {
parameters.put("name", "");
parameters.put("message", "");
}
Herramientas para la generación de código

Rediseñando el modelo para la interfaz:
model.design
Application Universe {
basePackage=org.helloworld
Module milkyway {
Service PlanetService {
String sayHello(String planetName);
protected findByExample =>
PlanetRepository.findByExample;
}
Entity Planet {
scaffold
String name key;
String message;
Integer diameter nullable;
Integer population nullable;
- Set<@Moon> moons opposite
planet;
Repository PlanetRepository {
findByExample;
findByKeys;
save;
}
}
Entity Moon {
not aggregateRoot // belongs to
Planet Aggregate
String name key;
Integer diameter nullable;
- @Planet planet opposite moons;
}
}
}
Herramientas para la generación de código

Modificando el modelo GUI (Vista) para:



Dar un nombre específico al cliente
Personalizar como se listan los planetas
Deshabilitar la posibilidad de editar el diámetro de un planeta
model.guidesign
import 'platform:/resource/sculptor-helloworld/src/main/resources/model.design'
gui TheFarFarAwayClient for Universe {
Module for milkyway {
ListTask for Planet {
name
diameter
population
}
UpdateTask for Planet {
name
population
}
}
}
Herramientas para la generación de código

Mas personalización en la introducción de datos de la interfaz:
“Cuando se crea un planeta, ninguna de sus lunas puede tener un
diámetro superior a el"

Crear un CreatePlanetValidatorTest y dejarlo en src/test/java
public void testValidatePlanet() {
// the form bean that is up for validation
CreatePlanetForm form = new CreatePlanetForm();
form.setName("FooPlanet");
form.setDiameter(1000);
Moon moon = new Moon("BarMoon");
moon.setDiameter(2000);
form.addMoon(moon);
BindException errors = new BindException(form, "createPlanetForm");
// the test target
CreatePlanetValidator validator = new CreatePlanetValidator();
validator.validatePlanet(form, errors);
assertTrue(errors.hasErrors());
}
Herramientas para la generación de código

CreatePlanetValidator:
@Override
public void validatePlanet(CreatePlanetForm form, Errors errors) {
Planet planet = form.toModel();
int planetDiameter = planet.getDiameter();
Collection<Moon> moons = planet.getMoons();
for (Moon moon : moons) {
if (planetDiameter <= moon.getDiameter()) {
errors.reject("createPlanet.faultyDiameter");
}
}
}
Herramientas para la generación de código

Estructura generada de la aplicación web CRUD:

Solo JSP:

src/main/webapp/WEB-INF/jsp => todos los jsp's.

Paginas generales (index.jsp, error.jsp) y otras especificas de los
domain objects

Cada modulo tiene una carpeta separada con las páginas, y cada
una tienen 2 partes. Una siempre se regenera (en carpeta
‘regenerated’) y otra solo la primera vez.

Por ejemplo, página de creación de planetas:




jsp/genereated/header.inc
jsp/milkyway/createPlanetForm.jsp (modificable)
jsp/generated/milkyway/createPlanetForm.inc
jsp/generated/footer.inc
Herramientas para la generación de código

Solo JSF:

src/main/webapp/WEB-INF/jsf => todos los xhtml’s.

Paginas generales (index.jsp, error.jsp) y otras especificas de los
domain objects

Cada modulo tiene una carpeta separada con las páginas, y cada
una tienen 2 partes. Una siempre se regenera (en carpeta
‘regenerated’) y otra solo la primera vez.

Por ejemplo, página de creación de planetas:




jsf/genereated/header.inc
jsf/milkyway/createPlanet.xhtml (modificable)
jsf/generated/milkyway/createPlanet.inc
jsf/generated/footer.inc
Herramientas para la generación de código

Parte Java

Igual que las clases del modelo del domino

Para cada objeto del dominio, hay clases generadas con
implementación de webflow:



Action: cada metodo CRUD usas su propia action (donde esta la
lógica de negocio)
Form: cada metodo CRUD usas su propio “portador” de datos
Validator: cada método CRUD usa su propia validador
Herramientas para la generación de código
Ficheros de configuacón::




web.xml
applicationContext.xml – Configuración de Spring
[application-name]-servlet-config.xml - Spring front controller
[application-name]-webflow-config.xml –Spring webflow

Además de los ficheros de configuración, cada metodo CRUD del Domain Object tiene su
configuración de navegación y su propio bean(WEB-INF/flows).

Create



Read






update-Planet-flow.xml
update-Planet-beans.xml
Delete


view-Planet-flow.xml
view-Planet-beans.xml
Update


create-Planet-flow.xml
create-Planet-beans.xml
delete-Planet-flow.xml
delete-Planet-beans.xml
Y además:
List


list-Planet-flow.xml
list-Planet-beans.xml
Herramientas para la generación de código

CSS

Sculptor genera un estilo por defecto y un tema Spring por defecto.

src/main/webapp/themes/basic/style.css
src/generated/resources/theme.properties.



Ejemplo: src/main/resources/blue.properties


Para añadir un tema propio, modificar el properties correspondiente de
src/main/resources/.
css=/themes/basic/blue.css
El tema cambia con el parámetro de petición ‘theme’:
<a href="index.htm?theme=theme">
<spring:message code="theme.default" text="Olive theme" /></a>
&nbsp;&nbsp;&nbsp;
<a href="index.htm?theme=blue"><spring:message code="theme.blue" text="Blue
theme" /></a>
Herramientas para la generación de código

Internacionalización

Los texto se definen en resource bundles. Sculptor genera resource bundles
con sugerencias solo en textos en Ingles. Para localizar un idioma especifico
se puede copiar los recursos de src/main/resources/i18n:
defaultMessages_en.properties
messages_en.properties
milkywayMessages_en.properties

sculptor-gui-generator.properties


gui.highlightMissingMessageResources=true => escribr el texto ‘???’ si no
encuentr el recurso para el idioma actual.
El idioma cambia con el parámetro de peticion ‘locale’:
<a href="index.htm?locale=en">
<spring:message code="language.en" text="English" /></a>
&nbsp;&nbsp;&nbsp;
<a href="index.htm?locale=sv_SE">
<spring:message code="language.sv" text="Svenska" /></a>
Herramientas para la generación de código


Campos obligatorios
Derivados del modelo.
'nullable‘ => no obligatorios
 En las referencias hay dos casos:


Para referencias 'one‘ se aplica la misma regla que en los atributos.
Referencia 'nullable‘ => no obligatorio

Para referencias 'many' no se dispone del ‘nullable’. Se usa entonces
'required'. Si la referencia es 'required‘ entonces la colección debe contener al
menos un elemento
Herramientas para la generación de código
DSL de la Vista



DSL para CRUD GUI
Incorporado desde la versión 1.5
Editar el fichero model.guidesign.
Herramientas para la generación de código

GUI DSL permite:





Especificar el nombre de la aplicación cliente
Especificar que atributos y referencia se deben listar y en que
orden
Especificar los métodos que se usan para visualizar, crear,
actualizar, listar y borrar.
Especificar los Domain Objects que deben ser omitidos
Especificar las tares que deben ser omitidas
Herramientas para la generación de código
import 'platform:/resource/fornax-cartridges-sculptor-exampleslibrary/src/main/resources/model.design'
gui Library for Library {
Module for person {
ListTask for Person {
name.first
birthDate
sex
ssn
}
}
}
Herramientas para la generación de código

Standard CRUD User Tasks

CreateTask. El objetivo es crear una nueva instancia de un Domain Object y guardarlo en
bbdd. La interfaz consiste en una entrada (formulario) y una pantalla de confirmación. Los
atributos se muestran tal cual y las referencias podemos editarlas o crear una nueva. La
operativa de la ejecución es en formato de wizard.

ListTask. El objetivo de esta tarea es mostrar todos o un subconjunto de los Domain
Objects. Su interfaz cosiste en en un tabla sencilla. Desde esta tarea se pueden abrir otras
como: ViewTask, DeleteTask y UpdateTask para objetos que ya existen.

UpdateTask es parecido a CreateTask, pero el objetivo es modificar.

ViewTask. El objetivo es mostrar información detallada de un Domain Object. La interfaz es
una sola pantalla con los datos del objeto y la posibilidad de navegar por sus referencias.

DeleteTask. El objetivo es borrar un Domain Object del almacenamiento. La interfaz
solicitará confirmación.
Herramientas para la generación de código
User Task
CreateTask
UpdateTask
ViewTask
DeleteTask
ListTask
AddTask
Define service operation with
createWith
findWith, saveWith
findWith
findWith,deleteWith
searchWith
findWith
Herramientas para la generación de código
Diseño interno del cartucho Sculptor

Sculptor Internal Design
Herramientas para la generación de código










1 – El desarrollador esta usando el editor de DSL para editar el
modelo de la aplicación (model.design). Las restricciones del DSL se
validan durante la edición.
2 – Cuando se genera el código de la aplicación, se lanza un
workflow.oaw específico.
3 – Este delega en sculptorworkflow.oaw, quien define el flujo del
proceso de generación de código
4 – Se inicia el análisis del model.design usando el parser de Xtext de
oAW.
5 – Transformación del modelo DSL a un metamodelo interno.
6 – Validación de restricciones
7 – Otra transformación del modelo.
8 – Otra validación de restricciones.
9 – Comienza la generación de código Java y de los ficheros de
configuración (se usan las plantiíllas Xpand de oAW).
10 – Las propiedades de la naturaleza técnica del proyecto se utilizan
por plantillas y helpers para finalizar la generación de código.
Herramientas para la generación de código

Generator Properties






Aspectos persoanlizables en el generador.
Valores por defecto en default-sculptor-generator.properties de
fornax-cartridges-sculptor-generator (ver repositorio).
Se pueden redefinir las propiedades en el fichero sculptorgenerator.properties y sculptor-gui-generator.properties.
Sculptor busca las propiedades en el siguiente orden de ficheros::
sculptor-gui-generator.properties
sculptor-generator.properties
default-sculptor-generator.properties
Herramientas para la generación de código

Project Nature

Por defecto es business-tier.
 Para un proyecto web:


project.nature=presentation-tier (para solo JSP)
Database Product

MySQL, Oracle y HSQLDB-InMemory

db.product=mysql
#db.product=oracle
#db.product=hsqldb-inmemory


Herramientas para la generación de código


Types
Mapeo de simple types usados en el DSL a generated types:




javaType.Date=java.util.Date
javaType.DateTime=java.util.Date
File Header
Se puede definir una cabecera automática en todos los
ficheros java generados

javaHeader=Copyright line 1 \n\ line 2 \n\ line 3
Herramientas para la generación de código


EJB Version
Por defecto EJB 3 pero soporta EJB 2.1



ejb.version=2.1
Scaffold
Operaciones definidas mediante lista separada por comas:

scaffold.operations=findById,findAll,save,delete
Herramientas para la generación de código

Business Tier Model (domain model)
Herramientas para la generación de código

GUI Model
Herramientas para la generación de código
AndroMDA
Herramientas para la generación de código
Indice



Introducción
Puesta en marcha
Primer Proyecto











Aplicaciones CRUD




Modelado, despliege y ejecución de la aplicación
Mejoras
Cartuchos y el motor de AndroMDA


Configuración del proyecto
Estructura del Proyecto
Fichero de configuración Maven
Resolución de Dependencias
Casos de Uso y modelado
Generacion, despliege y ejecución de la aplicación
Edición en Eclipse
Controladores de Presentación
Servicios
Mejoras
Merge-Point
Modificación de la vista y los estilos
Construcción de un cartucho
Herramientas para la generación de código
Introducción

Herramienta de generación de código.

Está “inspirada” en los principios de MDA, pero con
algunas limitaciones.

Características destacadas:





Herramienta popular de software libre.
Herramienta madura, desde 2002.
El foro de la herramienta suele ser activo y eficaz.
Utiliza el concepto de cartucho como plugin para la generación
de código.
Dispone de numerosos cartuchos para la plataforma Java.
Herramientas para la generación de código
Introducción

Características destacadas:







El desarrollo de aplicaciones está soportado por Maven,
aunque puede utilizarse con Ant.
Soporta el metamodelo UML y el formato XMI de los
principales editores: MagicDraw, Poseidon, RSM.
Utiliza OCL para la validación de los modelos.
La generación de código está basada en Velocity, aunque
pueden utilizarse otros motores de plantillas como
FreeMaker.
En general, la generación cubre la mayor parte del código, y
para algunas aplicaciones el 100%.
Recientemente se están desarrollando cartuchos para la
plataforma .NET.
Estudiaremos la herramienta a través de ejemplos.
Herramientas para la generación de código
Puesta en marcha

Java 6 SDK SE :


Eclipse 3.2 Callisto para Java:





http://java.sun.com/javase/downloads/index.jsp
Entorno de desarrollo.
http://www.eclipse.org/callisto/java.php
Java EE, Web Tools (Callisto discovery site)
Editor Velocity (http://veloedit.sourceforge.net/updates/)
MySQL:



Base de datos.
Sistema gestor + administración -> XAMPP
http://www.apachefriends.org/en/xampp-windows.html
Driver Java:http://dev.mysql.com/downloads/connector/j/5.0.html
Herramientas para la generación de código
Puesta en marcha



MagicDraw 9.5 Community Edition

Editor UML

http://www.magicdraw.com
Maven 2.0.5:

Gestor de proyectos

http://apache.rediris.es/maven/binaries/maven-2.0.5-bin.zip
JBoss 4.0.4:

Servidor de aplicaciones J2EE

http://downloads.sourceforge.net/jboss/jboss-4.0.4.GA.zip
Herramientas para la generación de código
Puesta en marcha


Plugin AndroMDA para Maven:

Generador de aplicaciones AndroMDA.

http://team.andromda.org/maven2/org/andromda/maven/plugins/andromd
app-maven-plugin/3.2/andromdapp-maven-plugin-install-3.2.zip
AndroMDA, código fuente, 3.2 y 3.3-SNAPSHOT


http://downloads.sourceforge.net/andromda/andromda-src-3.2.zip
http://andromda.org/maven2/org/andromda/distributions/andromda-src3.3-SNAPSHOT.zip
Herramientas para la generación de código
Puesta en marcha

Variables de entorno:

JAVA_HOME: directorio de instalación de Java.
Habitualmente “C:\Archivos de programa\Java\jdk...”

JBOSS_HOME: directorio de instalación.

M2_HOME: directorio de instalación de Maven.

M2_REPO: repositorio local de Maven


MAVEN_OPTS: opciones de Maven


Crear el directorio “C:\Documents and Settings\NOMBRE
USUARIO\.m2\repository”
-XX:MaxPermSize=128m -Xmx512m
PATH: añadir al PATH del sistema

%JAVA_HOME%\bin;%M2_HOME%\bin
Herramientas para la generación de código
Puesta en marcha


Prueba funcionamiento de Maven:

> mvn --version

Crear una aplicación,

> mvn archetype:create -DgroupId=testapp DartifactId=testapp
Descomprimir el plugin de AndroMDA para Maven en el
repositorio local:


... “.m2\repository\org\andromda\maven\plugins\andromda-maven-plugin\”
Copia el driver de la base de datos a la carpeta de JBoss
“server\default\lib” quitando el sufijo “bin” al nombre.
Herramientas para la generación de código
Puesta en marcha
Crear POM.XML y ejecutar mvn desde el mismo directorio:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>test</name>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.andromda.maven.plugins</groupId>
<artifactId>andromdapp-maven-plugin</artifactId>
<version>3.2</version>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>andromda</id>
<name>AndroMDA
Repository</name>
<url>http://team.andromda.org/maven2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>andromda</id>
<name>AndroMDA
Repository</name>
<url>http://team.andromda.org/maven2</url>
</pluginRepository>
</pluginRepositories>
</project>
Herramientas para la generación de código
Primer Proyecto

Un proyecto en AndroMDA es creado haciendo uso de un
plugin desarrollado para Maven.

> mvn org.andromda.maven.plugins:andromdapp-mavenplugin:3.2:generate

En la consola configuramos el proyecto:



Tipo de aplicación: richclient, j2ee
Directorio raíz sobre el que se creará el proyecto.
Versión de UML, que depende de la herramienta de modelado:



ArgoUML y MagicDraw 9.X: uml1.4
MagicDraw 11.5: uml2
Rational Rose Modeler 6: emf-uml2
Herramientas para la generación de código
Primer Proyecto

Configuración del proyecto (continuación):






Nombre del proyecto: Ejemplo.
Identificador del proyecto: debe ser una palabra sin espacios.
Representa el nombre de la carpeta del proyecto y el nombre de la
aplicación: ejemplo.
Versión del proyecto: 1.0, luego podemos variarla en el fichero de
configuración.
Paquete raíz del proyecto J2EE. Por ejemplo, para el grupo de
investigación GTS: es.um.inf.gts.ejemplo
Tipo de aplicación: WAR o EAR.
Selección del cartucho para la capa de negocio (persistencia y
servicios). Recomendable Spring.
Herramientas para la generación de código
Primer Proyecto

Configuración del proyecto (continuación):






Sistema gestor de base de datos. Para el ejemplo, mysql.
Decidir si queremos introducir un motor de Workflow. Para el
ejemplo elegimos “no”.
El cartucho Spring hace uso de Hibernate para la capa de
persistencia. Nos solicita la versión de Hibernate, 2 ó 3.
Decidimos si queremos una interface web: respondemos
“yes”.
Seguidamente nos pregunta por el framework web: jsf o
struts.
Por último, nos pregunta si los servicios deben ser expuestos
como servicios web. Respondemos “no”.
Herramientas para la generación de código
Configuración del proyecto


En resumen, cuando configuramos un proyecto decidimos la
tecnología que será utilizada en las capas de la aplicación.
Una aplicación J2EE consta de las siguientes capas:


Capa de presentación (web): JSF o Struts (opcional)
Capa de negocio: EJB, Spring, Hibernate o ninguna.




Podemos exponer los servicios de negocio como servicios web.
Capa de persistencia: Hibernate 2 ó 3.
Sistema de almacenamiento: Oracle, Mysql, Postgres, etc.
Independientemente decidimos el metamodelo: UML 1.4, UML
2.0, EMF UML 2.0.
Herramientas para la generación de código
Estructura del Proyecto


El asistente crea un proyecto Maven que contiene a su vez
varios subproyectos:
ejemplo\ -> proyecto principal

mda\ contiene el modelo UML y el fichero de configuración
de AndroMDA.

core\ incluye el código y recursos de la capa de negocio.

web\ corresponde a la capa de presentación

common\ incluye recursos y código compartidos entre la
capa de negocio y web,ej. los “value objects”

app\ contiene los recursos y código necesarios para
ensamblar la aplicación.
Herramientas para la generación de código
Fichero de configuración Maven

En la raíz del proyecto encontramos dos ficheros:

pom.xml: descriptor del proyecto Maven.

readme.txt: describe extensamente la estructura del proyecto
y los comandos Maven para trabajar con el proyecto:
validación, compilación, despliegue, etc.

El fichero descriptor del proyecto resulta “complejo” a
primera vista.

En resumen, contiene información sobre el proyecto,
dependencias respecto a otras librerías y proyectos, y
establece una serie de propiedades.
Herramientas para la generación de código
Base de Datos

El aspecto más importante del fichero pom.xml es el relativo a la
configuración de la base de datos.
En el asistente se ha definido el tipo de sistema gestor.

Hay que definir manualmente:


Driver de la base de datos: etiqueta <jdbc.driver.jar>.

Si se ha copiado el driver en el servidor JBoss:
${jboss.home}/server/default/lib/mysql-connector-java-5.0.5.jar

La etiqueta <jdbc.url> apunta a la URI de la base de datos, cuyo
nombre es ejemplo (no hay que tocar la propiedad)

Las etiquetas <jdbc.username> y <jdbc.password> representan las
credenciales. Estableceremos ejemplo y ejemplo.
Herramientas para la generación de código
Creación de la Base de Datos

Se ha instalado el sistema gestor MySQL junto con la
herramienta de administración PHPMyAdmin utilizando la
distribución XAMPP.

Ejecutamos el Panel de Control de XAMPP y arrancamos los
servicios Apache y MySQL.

Seguidamente, en el navegador web escribimos la dirección:
http://localhost/phpmyadmin/

El objetivo es crear la base de datos “ejemplo” y el usuario
“ejemplo”.

Pulsamos el enlace “Privilegios” de la página inicial.

Seguidamente el enlace “Agregar un nuevo usuario”.
Herramientas para la generación de código
Creación de la Base de Datos

En “Información de la cuenta” introducimos:

Nombre de usuario: ejemplo.

Servidor: localhost (indica desde donde se permiten las
conexiones).

Contraseña: ejemplo.

En el apartado “Bases de datos para el usuario” marcamos
“Crear base de datos ...” y por último el botón “Continuar”.

Regresamos a la página inicial, y pulsamos “Cargar los
privilegios nuevamente” para que se actualicen los
cambios.
Herramientas para la generación de código
Resolución de Dependencias

El proyecto establece numerosas dependencias con otro
software: Struts, Hibernate, Spring, etc.

Para resolver las dependencias, podemos construir el
proyecto con el comando > mvn install

Maven trata de localizar las dependencias en el
repositorio local.

Si no lo consigue, las descarga desde un repositorio
remoto (especificado en pom.xml) y actualiza el
repositorio local.
Herramientas para la generación de código
Resolución de Dependencias

En ocasiones, el repositorio remoto por defecto de
AndroMDA no aloja todas las dependencias.

Suele ser conveniente actualizar la sección repositories
del fichero de “pom.xml”, añadiendo el repositorio de
Sun:
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven 2</name>
<url>https://maven2repository.dev.java.net/nonav/repository</url>
</repository>
Herramientas para la generación de código
Requisitos de la Aplicación




Queremos desarrollar una aplicación web Java para la
gestión de los modelos de coches de un concesionario.
Un modelo de coche se caracteriza por el fabricante, el año de
fabricación, y el modelo propiamente. El año de fabricación es
un campo opcional.
Deseamos obtener un listado de todos los modelos así como
poder realizar el alta y eliminación.
La aplicación mostrará inicialmente el listado con los modelos
y tras las operaciones de inserción y borrado, el listado volverá
a ser presentado.
Herramientas para la generación de código
Casos de Uso

Listado de coches:


Alta coche:



Presenta un listado con todos los modelos de coches del
concesionario.
Realiza el alta de un coche. El usuario introduce los datos:
fabricante, modelo y fecha, siendo este último opcional.
El sistema asigna un identificador automático a cada nuevo
modelo.
Eliminación coche:

El usuario indica al sistema el identificador del coche que debe ser
eliminado.
Herramientas para la generación de código
Modelado con MagicDraw 9.5


El modelo de la aplicación reside en la carpeta
“mda/src/main/uml/”.
El modelo utiliza varios perfiles UML:



Datatype: representa los tipos de datos primitivos de UML.
Perfiles de AndroMDA: persistence, presentation, service, etc.
necesarios para modelar las capas de la aplicación.
Paso 1: Creación de un modelo.


Sobre el elemento “Data” del Árbol de Contenido creamos un
nuevo elemento “Modelo” que podemos nombrar como
“Ejemplo”.
Y dentro el paquete raíz del proyecto: “es.um.inf...”
Herramientas para la generación de código
Modelado - Requisitos

Paso 2: Requisitos.


Creamos un paquete dentro del modelo llamado “requisitos”.
Dentro de este paquete situamos un diagrama de casos de uso
que llamados “Requisitos de la Aplicación”.
Herramientas para la generación de código
Modelado - Requisitos

Paso 2: Requisitos, reglas de modelado

El actor no es imprescindible para la generación de código.
Será útil si se introduce seguridad basada en roles.

Los casos de uso (CdU) que interaccionan con el usuario
deben marcarse con el estereotipo “FrontEndUseCase”.

En la aplicación debe haber un caso de uso inicial, que será
marcado adicionalmente con el estereotipo
“FrontEndApplication”.
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 3: Diagramas de Actividades

Cada cdu será definido mediante un diagrama de actividad.

Los diagramas serán utilizados para la generación de la capa de
presentación.

Por tanto, creamos un paquete llamado “presentacion”, donde
crearemos un paquete por cada cdu.

Dado que los nombres de los paquetes tienen correspondencias
directas con Java, es recomendable que se escriban en
minúscula.

Por organización, es recomendable mover los cdu desde el
paquete de requisitos al paquete correspondiente de la capa de
presentación.
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 3: Diagramas de Actividades

En el Árbol de Contenido, seleccionamos cada cdu y le asociamos
un diagrama de actividad. El nombre de los diagramas debe ser
simplemente significativo.

Las acciones asociadas a los diagramas de actividades son
realizadas por clases controladoras de la capa de presentación.

Para cada cdu creamos en su paquete una clase controladora:
ControladorListadoCoches, etc.

Asignamos a la clase controladora el diagrama de actividades
asociado al cdu: seleccionamos el elemento en el Árbol de
Contenido, opción “Diagrama de Actividad/Estado” y “Asignar ...”
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 4: Diagrama de Actividad – Listado de Coches

Para facilitar la construcción del diagrama, puede ser conveniente
expresar textualmente el flujo del cdu.

Flujo CdU “Listado de Coches”:



1. Sistema: Obtener coches
2. Sistema: Mostrar Listado de Coches al Usuario
3. Usuario: alternativa



3.1: Solicitar Alta de Coche
3.2: Introducir ID del modelo de coche a eliminar y solicitar su borrado.
Con el diagrama de actividad trataremos de reflejar el flujo del cdu
expresado textualmente.
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 4: Diagrama de Actividad – Reglas de Modelado





Por claridad es recomendable crear dos swimlanes, uno para el
Sistema y otro para el Usuario.
Las tareas que realiza el sistema se modelan como Acciones.
Estas acciones delegan su tarea en la clase controladora mediante
una llamada diferida a uno de sus métodos.
Si la acción retorna información, ésta será transferida a una vista a
través de una transición. Se modela como una señal y los datos se
representan como parámetros.
Los parámetros de la señal deben corresponder exactamente en
nombre, tipo y orden con los parámetros del método del
controlador.
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 4: Diagrama de Actividad – Reglas de Modelado

Las tareas que implican mostrar una vista al usuario, se
modelan como Acciones marcadas con el estereotipo
“FrontEndView”.

Si reciben información a través de una transición de
entrada, estará disponible en la vista.

Las acciones del usuario sobre la vista se modelan como
transiciones de salida.

Estas transiciones también se representan como señales.
En este caso, se les asocia el nombre de la acción (alta,
eliminación) y si recogen información de un formulario o
enlace se indican como parámetros.
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 4: Diagrama de Actividad – Reglas de Modelado

Las transiciones de salida de un vista pueden conducir a
una tarea del sistema o a otro cdu.

En el primer caso, el método del controlador asociado a la
acción tendrá los mismos parámetros que la transición de
salida.

En el segundo, la transición acaba en un estado final cuyo
nombre corresponde exactamente con el cdu destino.

Además, es posible transferir información entre cdus.
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Diagrama de Actividad: Listado de Coches
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 5: Diagrama de Actividad – Alta Coche
El estado final conduce al CdU Listado
de Coches
Herramientas para la generación de código
Modelado – Diagramas de Actividades

Paso 6: Diagrama de Actividad – Eliminación Coche
El “id” se obtiene del
CdU Anterior
Herramientas para la generación de código
Modelado – Capa de Negocio

Paso 7: Modelo de Dominio




Creamos el paquete “dominio” y un diagrama de clases
donde se definen las entidades de negocio y sus relaciones.
Las clases que representan a una entidad son marcadas con
el estereotipo “Entity”.
Las propiedades de las entidades se modelan como atributos
públicos.
Paso 8: Servicios


Los servicios representan una fachada a la capa de negocio.
Creamos el paquete “servicios” y un diagrama de clases
donde cada servicio es una clase con el estereotipo “Service”.
Herramientas para la generación de código
Modelado

Paso 9: Dependencias entre las capas





La capa de presentación accede a la capa de servicios que a su
vez se comunica con la capa de negocio.
Estas relaciones se establecen mediante relaciones de
dependencia entre las clases.
Estas relaciones permiten al desarrollador obtener referencias
“transparentes” a otras capas sin conocer la tecnología de
implementación de ellas.
Habitualmente, las relaciones de dependencia se expresan en un
diagrama de clases, que suele ser el de los servicios.
En el ejemplo, por simplicidad creamos un solo paquete,
“dominio”, y un solo diagrama de clases.
Herramientas para la generación de código
Diagrama de Clases
Herramientas para la generación de código
Otros aspectos de modelado

Aspectos a tener en cuenta:





Un controlador de la capa de presentación no tiene por qué
comunicarse con un solo servicio.
Un patrón habitual de las aplicaciones J2EE es que la capa de
presentación y de servicios transfiera los datos a través de “Value
Object”. Mejora el rendimiento reduciendo el número de llamadas
remotas.
Por tanto, la signatura de los métodos de la capa de presentación
y de servicios suele ser diferente.
Se podría prescindir de la capa de servicios en aplicaciones
sencillas.
Sin embargo, la capa de servicios ofrecen operaciones
transaccionales a la capa de presentación.
Herramientas para la generación de código
Generación de Aplicación



El modelado de la aplicación suele ser iterativo.
Los cartuchos de AndroMDA establecen restricciones de
modelado que son chequeadas sobre el modelo.
Podemos ir comprobando si se cometen errores de
modelado generando la aplicación con:



> mvn install
Si existen errores, se detiene el proceso de generación y se
muestra una lista con los errores.
Si la generación es correcta y el modelo de dominio ha
cambiado desde la última generación, debemos actualizar
el esquema de la base de datos:

> mvn -f core/pom.xml andromdapp:schema Dtasks=drop,create
Herramientas para la generación de código
Despliegue de la Aplicación

Una vez generada la aplicación, el siguiente paso es
desplegarla en el servidor de aplicaciones (JBoss).

Utilizamos el comando:


> mvn -f app/pom.xml -Ddeploy
Probamos el funcionamiento de la aplicación:

http://localhost:8080/ejemplo/
Herramientas para la generación de código
Ejecución de la Aplicación
Herramientas para la generación de código
Aspectos a destacar de la ejecución

Del resultado de la ejecución destacamos:






Los enlaces a los cdu se muestran en un menú lateral.
La aplicación comienza por el cdu inicial “Listado de Coches”.
La aplicación no actúa sobre la capa de negocio!! Podemos
comprobarlo consultando la base de datos.
El listado sólo muestra datos de relleno.
En realidad, aunque se establezcan dependencias entre las
capas, AndroMDA no genera el código de las llamadas.
Por tanto, es necesario un poco de codificación manual para
establecer la conexión entre las capas.
Herramientas para la generación de código
Estrategia de Generación de Código

Algunas herramientas MDA utilizan la técnica de bloques
protegidos para que el usuario introduzca código dentro de
las clases generadas.

Sin embargo, AndroMDA utiliza herencia y métodos
abstractos para separar el código generado
automáticamente del código manual.

El mejor modo de estudiar el código generado es a través
de un IDE.

Al crear el proyecto, AndroMDA se generan los ficheros
“.classpath” y “.project” que definen un proyecto Eclipse.
Herramientas para la generación de código
Edición en Eclipse

Una vez arrancado el entorno Eclipse, importamos el
proyecto en el espacio de trabajo.

En caso de que no se haya activado automáticamente,
activamos la perspectiva Java.

En la perspectiva Java pueden aparecernos numerosos
errores debido a que Eclipse no conoce las librerías de las
que depende el proyecto.

En Preferencias/Java/Build Path/Classpath variables,
definimos la variable “M2_REPO” para que apunte al
repositorio local de Maven 2.
Herramientas para la generación de código
Código Fuente

El código fuente se organiza en cinco carpetas, cada una
asociada a un subproyecto: web, common y core.

Las carpetas que incluyen la subcarpeta “target” indican que el
código que contienen no debe ser modificado, ya que se
actualiza en cada generación.

Las que contienen la subcarpeta “src/main/java” contienen el
código para edición manual.

En el proyecto tenemos dos, una para la capa web y otra para la
capa de negocio (core).

Normalmente, las clases “manuales” acaban con el sufijo “Impl”.
Herramientas para la generación de código
Controladores de Presentación

Controlador “Listado de Coches”:




AndroMDA crea una clase interna para incluir datos de
relleno en el listado. Podemos eliminar el atributo y la clase
interna.
El método que contiene debe obtener un listado con los
coches y establecerlo en la transición de salida de la acción.
El parámetro “form” es un JavaBean que tiene métodos
get/set para establecer todos los parámetros del método del
controlador.
En este caso, hay que establecer un parámetro de salida, y
se utilizará el método “setCoches”.
Herramientas para la generación de código
Controladores de Presentación

Controlador “Listado de Coches”:

En el diagrama de clases se estableció una dependencia entre
el controlador y el servicio “ServicioCoches”.

Accedemos al servicio con la llamada
“this.getServicioCoches()”.

Una vez obtenida la referencia, se obtienen los datos
llamando al método que retorna todos los coches:
“getAllCoches()”.
Herramientas para la generación de código
Controladores de Presentación

Controlador “Alta Coche”:

De nuevo, eliminamos el código de relleno.
El método del controlador recibe los parámetros de la transición
de entrada con los que debe crear el coche.

Incluimos el siguiente código:

this.getServicioCoches().createCoche(
form.getFabricante(),
form.getModelo(),
form.getAnyoFabricacion());
Herramientas para la generación de código
Controladores de Presentación

Controlador “Eliminación Coche”:

Eliminamos el código de relleno.

El método recibe el identificador del coche como parámetro
de entrada.

Incluimos el siguiente código:
this.getServicioCoches().removeCoche(
form.getId());
Herramientas para la generación de código
Servicios

Implementamos las operaciones del Servicio de Gestión de
Coches.

Los nombres de las operaciones son prefijados por
“handle”.

Los servicios acceden a la capa de persistencia utilizando
el patrón DAO.

Si en el diagrama de clases se establece una relación de
dependencia con la entidad Coche, la clase dispone de la
operación ”this.getCocheDao()”.

La clase DAO define una serie de operaciones para crear,
recuperar y eliminar los objetos de ese tipo.
Herramientas para la generación de código
Servicios

Operación “createCoche”:


Operación “getAllCoches”:


return this.getCocheDao().loadAll();
Operación “removeCoche”:


this.getCocheDao().create(fabricante, modelo,
anyoFabricacion);
this.getCocheDao().remove(Long.valueOf(id));
Nota: por defecto, para una entidad se crea una clave
primaria de tipo entero (Long) que es utilizada para
operaciones de recuperación (“load”) y borrado
(“remove”) de la clase DAO.
Herramientas para la generación de código
Ejecución con acceso a la capa de negocio
Herramientas para la generación de código
Aspectos a mejorar

Aspectos a mejorar:

Cabecera del listado significativa.

En los formularios de alta y eliminación, indicar los campos
obligatorios y opcionales.

Eliminar el banner de la herramienta.

Modificar los estilos y el layout.

Cambiar el idioma de los mensajes.

...
Herramientas para la generación de código
Mejoras en el modelo





No todas las mejoras pueden conseguirse editando el modelo.
Algunas requieren modificar el proceso de generación (se verá
más adelante).
Sin embargo, la cabecera de la tabla y los campos
obligatorios y opcionales se pueden establecer en el modelo
estableciendo “valores etiquetados”.
La mayoría de los elementos del modelo disponen de valores
etiquetados para ajustar la generación.
Estos valores pueden ser dependientes o independientes de
la plataforma.
Herramientas para la generación de código
Mejoras en el modelo

Definición de la cabecera del listado:





Nos situamos en el diagrama de actividad del “Listado de
Coches”.
Los datos que representan el listado fluyen en la transición que
llega a la vista “Mostrar Listado de Coches”.
El elemento de modelado es un parámetro del trigger que
representa la señal.
Podemos observar la relación de valores etiquetados.
Algunos son independientes de la tecnología de presentación,
otros dependen de la tecnología web, y otros del framework
Struts.
Herramientas para la generación de código
Mejoras en el modelo

Definición de la cabecera del listado:


Establecemos el valor etiquetado
[email protected] con valor
“ID, AnyoFabricacion, Fabricante, Modelo”.
Campos obligatorios en formularios:

Los formularios corresponden a las transiciones de salida
con parámetros de las vistas.

De nuevo, los campos del formulario son los parámetros de
la señal de la transición.

Establecemos al valor “true” el valor etiquetado
[email protected] de los
campos obligatorios.
Herramientas para la generación de código
Mejoras en el modelado
Herramientas para la generación de código
Ajustes en los cartuchos

Los ajustes que deben realizarse sobre el proceso de
generación (cartuchos) requieren conocimientos sobre las
tecnologías que se utilizan.

Ejemplo:



Para modificar el layout hay que conocer que el layout está
definido mediante el framework Tiles
En este framework el layout se configura en el fichero “tilesdefs.xml” de la carpeta “WEB-INF” ...
Se verá más adelante un ejemplo.
Herramientas para la generación de código
Aplicaciones CRUD

El ejemplo desarrollado es sencillo y está limitado a las
operaciones típicas de creación, eliminación y consulta (ha
faltado la operación de actualización).

Sin embargo, se puede observar que un gran número de
aplicaciones de gestión están basadas en esas
operaciones: aplicaciones CRUD.

La generación de código para estas aplicaciones podría ser
completa.

AndroMDA define el estereotipo “Manageable” en el
cartucho Spring/Hibernate para indicar las entidades con
operaciones CRUD.
Herramientas para la generación de código
Modelado de la Aplicación

Creamos una nueva aplicación llamada “crud” con los
mismos valores de configuración.

Y una base de datos con nombre “crud” y un usuario con el
mismo nombre y clave.

Configuramos la aplicación para que trabaje con esa base de
datos.

Editamos el modelo UML del siguiente modo:

Creamos un modelo y el paquete “es.um.inf.gts.crud”.

Dentro de este paquete editamos un diagrama de clases e
incluimos la entidad Coche con los atributos del ejemplo
anterior y con los estereotipos “Entity” y “Manageable”.
Herramientas para la generación de código
Despliegue en JBoss

JBoss no permite desplegar una aplicación EAR si el
fichero de configuración (ejb-jar.xml) está vacío.

Si la aplicación sólo tiene entidades CRUD, no hay
servicios EJB, y por tanto mostrará un error.

El problema tiene una solución sencilla creando un
servicio de relleno.

Finalmente, con Maven:

Compilamos el proyecto

Actualizamos el esquema de la base de datos

Desplegamos la aplicación.
Herramientas para la generación de código
Ejecución de la aplicación CRUD
Herramientas para la generación de código
Ejecución de la aplicación CRUD

Aspectos a destacar:

A la derecha aparece el cdu “Entity Management” para la gestión de
todas las entidades con el estereotipo “Manageable”.

En las consultas se puede utilizar cualquier criterio incluyendo los
típicos caracteres comodín como “%”.

Si se marca una fila, se puede actualizar el registro correspondiente.

Se pueden marcar varios registros para ser eliminados.

El listado es paginado y se puede ordenar por el criterio de las
columnas.

...
Herramientas para la generación de código
Nuevos Requisitos

El desarrollo de aplicaciones CRUD con AndroMDA es
sencillo y productivo.

Ampliamos los requisitos de la aplicación de ejemplo para
aprovechar estas posibilidades:

Queremos ofrecer la opción de realizar pedidos sobre alguno
de los modelos de coches.

Un pedido se caracteriza por la fecha, medio de pago (tarjeta
de crédito, transferencia), y la cantidad del modelo que se
compra.

Los pedidos van asociados a un cliente, que se define por su
nif (atributo único), nombre, apellidos y teléfono (opcional).
Herramientas para la generación de código
Diagrama de Clases
Herramientas para la generación de código
Ejecución de la Aplicación
Herramientas para la generación de código
Ejecución de la Aplicación
Herramientas para la generación de código
Ejecución de la Aplicación
Herramientas para la generación de código
Modelado de la aplicación

Aspectos a destacar del modelado:

Un campo opcional se indica en el modelo estableciendo la
cardinalidad del atributo a 0..1

Los atributos marcados como “Unique” representan la clave
primaria e identifican a la entidad en las asociaciones.

Si una entidad no tiene ninguno, se le asignará un
identificador numérico (ejemplo entidad Pedido).

Las asociaciones navegables deben ser públicas.

Se ha utilizado un enumerado para el tipo de transferencia.
Herramientas para la generación de código
Mejoras en aplicaciones CRUD




Al igual que en el primer ejemplo, la generación de código por
defecto puede tener algunas limitaciones.
De nuevo, en el modelo podemos editar los valores
etiquetados de los elementos y establecer propiedades
independientes de la plataforma (ej. la validación de un campo)
o propiedades específicas (persistencia con Hibernate).
Sin embargo, el grado de control es más limitado, ya que
tenemos menos elementos de modelado (sólo un diagrama de
clases).
En cualquier caso, se puede modificar la generación de los
cartuchos.
Herramientas para la generación de código
Cartuchos

Un cartucho representa un módulo de generación de
código.

Define el perfil UML que procesa, las plantillas encargadas
de la generación, recursos, y propiedades que lo
configuran.

Los cartuchos no establecen “formalmente” dependencias
entre sí.

Sin embargo, pueden cooperar en el proceso de
generación: Spring utiliza Hibernate.
Herramientas para la generación de código
Motor de AndroMDA

Paso 1: El motor de la herramienta “detecta” los cartuchos
disponibles (situados en el classpath del proyecto).

Paso 2: Para cada cartucho establece un dominio de
ejecución configurado por una serie de propiedades
(namespace).

Paso 3: Analiza cada cartucho para averiguar los
elementos de modelado y restricciones que procesa.

El conjunto de todos esos elementos y restricciones define el
metamodelo origen de la generación.
Herramientas para la generación de código
Motor de AndroMDA

Paso 4: Carga el modelo en un repositorio


Paso 5: Localiza en el modelo los elementos de modelado.


Actualmente sólo procesa modelos UML que son cargados en el
repositorio MDR NetBeans y los procesa utilizando el API
estándar JMI.
Si los cartuchos lo indican, instancia objetos fachada
(metafachadas) que enriquecen los objetos JMI.
Paso 6: Para cada elemento localiza las plantillas de
generación.

Un cartucho puede tener más de una plantilla para un mismo
elemento y varios cartuchos pueden estar interesados en ese
elemento.
Herramientas para la generación de código
Motor de AndroMDA

Paso 7: Modificaciones particulares de la generación.
Antes de aplicar una plantilla comprueba:


Si el proyecto requiere insertar modificaciones (merge points).
Si el proyecto define plantillas y recursos propios que
sustituyan a los del cartucho.

El proceso de generación finaliza cuando todos los elementos
de interés del modelo hayan sido procesados.

Tras la generación, siguen otras fases de desarrollo definidas
por Maven: compilación, pruebas, etc.
Herramientas para la generación de código
Modificación de la generación


La generación de un cartucho puede ser alterada de los
siguientes modos:

Estableciendo merge points.

Incluyendo en el proyecto plantillas o recursos propios que
sustituyan los del cartucho.

Modificando el cartucho.
En general, todas las modificaciones requieren
conocimientos de la tecnología del cartucho y de su
implementación.
Herramientas para la generación de código
Merge Point

Un merge point es un punto de cualquier recurso textual de
un cartucho que puede ser reemplazado.

Son definidos por el desarrollador del cartucho en los
puntos donde se permite añadir contenido.

Habitualmente, en los cartuchos estándares de AndroMDA
no están bien documentados.

La sustitución de los merge points es declarada en un
fichero XML de mappings.
Herramientas para la generación de código
Merge Point - Ejemplo

Ejemplo:

La mayor parte de las plantillas de generación de código Java
incluyen la siguiente línea al principio de la plantilla para
establecer la licencia de código:
// license-header java merge-point


Podemos reemplazar este merge point para incluir la licencia
de la empresa u organización.
Paso 1: identificamos el cartucho o cartuchos para los que
queremos definir el merge point. En el ejemplo: Spring.
Herramientas para la generación de código
Merge Point - Ejemplo

Paso 2: Editamos el fichero de configuración de
AndroMDA.

Localización: “mda/src/main/config/andromda.xml”

En el namespace “spring”, añadimos la siguiente propiedad:
<property name="mergeMappingsUri">
file:${conf.dir}/mappings/SpringMergeMappings.xml
</property>

La propiedad indica el fichero de definición de las
correspondencias o mappings.
Herramientas para la generación de código
Merge Point - Ejemplo

Paso 3: Definición de las correspondencias
 El fichero establece correspondencias entre
fragmentos de texto..
 El fichero puede contener varias correspondencias.
<mappings name="SpringMerge">
<mapping>
<from><![CDATA[// license-header java mergepoint]]></from>
<to>
<![CDATA[// Desarrollado por Marcos ]]>
</to>
</mapping>
</mappings>
Herramientas para la generación de código
Plantillas y recursos propios

El motor de AndroMDA, antes de copiar un recurso a su
ubicación destino o de procesar una plantilla, comprueba
si en el proyecto existe una versión propia.

En el namespace del cartucho se indica la localización de
las plantillas y recursos propios.

La ubicación de los recursos o plantillas en el proyecto
debe coincidir con la ruta relativa definida en el cartucho.
Herramientas para la generación de código
Modificación del layout de la vista

Ejemplo: modificar el layout de la aplicación.
Quitar
“breadcrumbs”
Quitar
publicidad
de
AndroMDA
Quitar
mensaje
Herramientas para la generación de código
Modificación del layout de la vista

El framework Struts ha sido seleccionado para la
implementación de la capa web.

Struts utiliza el framewok Tiles para definir el layout de la
aplicación.

El objetivo es localizar las plantillas y recursos que hay
que modificar y crear versiones propias para el proyecto.

En “andromda.xml”, namespace “bpm4struts”, indicamos
la localización de estos ficheros:
<property name="mergeLocation">
${web.manual.dir}/customTemplates
</property>
Herramientas para la generación de código
Modificación del layout de la vista


El fichero de configuración de Tiles se llama “tilesdef.xml”:

Se localiza en la carpeta WEB-INF de una aplicación web.

Carpeta “web/target/src/WEB-INF” del proyecto.
Localizamos la plantilla en el fichero JAR del cartucho o
en el código fuente de AndroMDA.

El fichero JAR se encuentra en el repositorio Maven.

En el código fuente está en la carpeta
“cartridges/BPM4Struts/src/”.
Herramientas para la generación de código
Modificación del layout de la vista


Análisis del fichero “tiles-def.xml”:

La definición de los “breadcrumbs” se realiza en la página
“layout/breadcbrumbs.jsp”.

El panel lateral derecho de la página se define en
“layout/menu.jsp”.
Localización de las plantillas:


Nombre del fichero acabado en “.vsl”.
Se encuentran en “templates/bpm4strust/pages”.

Replicamos la estructura de directorios en
“web/src/customTemplates”.

Copiamos las plantillas para su modificación.
Herramientas para la generación de código
Modificación del layout de la vista

Modificación “breadcbrumbs.jsp.vsl”:



Modificación “menu.jsp.vsl”:

Eliminamos el bloque “div” con la publicidad de AndroMDA
(“box1”).

Y el bloque con la información de generación (“box3”).
Eliminamos la última generación:


Dejamos vacío el bloque <div> con del contenido.
> mvn clean
Generamos de nuevo el proyecto:

> mvn install
Herramientas para la generación de código
Resultado Modificación Layout
Herramientas para la generación de código
Modificación de los estilos


No toda la aplicación se genera a partir de plantillas.
Hay recursos que directamente se copian a la aplicación
generada.


Por ejemplo, los estilos de la aplicación.
Objetivo:




Queremos que los hiperenlaces no aparezcan punteados.
Localizamos el fichero de estilos en el cartucho:
“resources/default.css”.
Replicamos la estructura en el proyecto y copiamos el recurso.
Editamos el recurso: modificamos las reglas “a:link” y “a:visited”
y sustituimos “dotted” por “solid”.
Herramientas para la generación de código
Modificación de los estilos
Herramientas para la generación de código
Modificación del cartucho

Si los cambios en el proceso de generación deben ser
aplicados a varios proyectos, tenemos dos opciones:





Modificación del código fuente del cartucho.
Edición del fichero JAR del cartucho y actualizar los ficheros
que hayan variado: “resources” y “templates”.
La primera opción debe emplearse si los cambios requieren
modificaciones en el código Java.
La segunda opción es la más sencilla y recomendable si
sólo modificamos plantillas y recursos.
La modificación de los cartuchos suele utilizarse en
empresas donde ya existen normas de desarrollo:
convenciones de nombrado, organización, interfaces, etc.
Herramientas para la generación de código
Desarrollo de un nuevo cartucho






AndroMDA proporciona un soporte irregular para la
construcción de cartuchos.
No tiene un generador de un proyecto de cartucho.
La recomendación es “copiar” uno ya desarrollado y
adaptarlo.
El desarrollo de cartuchos se basa en el concepto de
“metafachada”.
Una metafachada es una clase que envuelve a un elemento
de modelado, enriqueciendo sus propiedades con el fin de
facilitar la generación de código a las plantillas.
La herramienta ofrece metafachadas para la mayor parte de
UML.
Herramientas para la generación de código
Ejemplo de Cartucho

Objetivo:



Procesar las clases de un modelo con el estereotipo “Prueba” y
generar una clase Java vacía para cada una.
Si tiene un determinado valor etiquetado, se incluye
documentación en la clase con ese valor.
Ficheros de configuración del cartucho:



Carpeta “src/META-INF/andromda/”:
cartridge.xml: fichero principal que contiene las asociaciones
entre las plantillas y las metafachadas.
metafacades.xml: contiene la declaración de las metafachadas.
Herramientas para la generación de código
Ejemplo de Cartucho

Ficheros de configuración del cartucho:



namespace.xml: define el namespace del cartucho
y las propiedades de configuración.
profile.xml: definición del perfil UML
(metamodelo) que procesa el cartucho.
La carpeta “uml” contiene el modelo de las
metafachadas:



En general, se suele extender una metafachada de
AndroMDA para añadir características propias de
la generación.
Podrían utilizarse sólo las de AndroMDA.
Suelen incluir restricciones OCL que se utilizan
para la validación de los modelos.
Herramientas para la generación de código
Construcción del cartucho

Generación de las metafachadas:



Comando > mvn install
El resultado es el siguiente:

PruebaFacade: define el tipo de la metafachada.

PruebaFacadeLogic: codificación automática de la
metafachada.

PruebaFacadeLogicImpl: clase para incluir código manual.
Si la clase definiera atributos o métodos, habría que editar
el código manual.
Herramientas para la generación de código
profile.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<profile>
<elements>
<elementGroup name="Stereotypes">
<element name="PRUEBA">
<documentation>
Ejemplo de definición de un estereotipo
</documentation>
<value>Prueba</value>
<appliedOnElement>class</appliedOnElement>
</element>
</elementGroup>
</elements>
</profile>
Herramientas para la generación de código
namespace.xml
<namespace name="cartucho-prueba">
<components>
<component name="cartridge"><path>META-INF/andromda/cartridge.xml</path>
</component>
<component name="profile"><path>META-INF/andromda/profile.xml</path>
</component>
<component name="metafacades"><path>META-INF/andromda/metafacades.xml</path>
</component>
</components>
<properties>
<propertyGroup name="Outlets">
<property name="salida" required="false">
<documentation>Localización ficheros de salida
</documentation>
</property>
</propertyGroup>
</properties>
</namespace>
Herramientas para la generación de código
metafacades.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<metafacades>
<metafacade
class="es.um.inf.gts.cartucho.metafachadas.PruebaFacadeLo
gicImpl">
<mapping
class="org.omg.uml.foundation.core.UmlClass$Impl">
<stereotype>PRUEBA</stereotype>
</mapping>
</metafacade>
</metafacades>
Herramientas para la generación de código
cartrigde.xml
<cartridge>
...
<template path="templates/Prueba.vsl"
outputPattern="{1}.java" outlet="salida" overwrite="true">
<modelElements>
<modelElement variable="clase">
<type
name="es.um.inf.gts.cartucho.metafachadas.PruebaFacade" />
</modelElement>
</modelElements>
</template>
<!-- cartridge-template merge-point -->
</cartridge>
Herramientas para la generación de código
Pruebas




El desarrollo de un cartucho incluye una fase de pruebas.
Las pruebas consisten en aplicar el cartucho a un
proyecto AndroMDA y comprobar que la generación es
correcta.
La configuración del proyecto de pruebas está en la
carpeta “conf/test”.
 Se establecen las propiedades del cartucho.
La carpeta “src/test” contiene:
 El modelo de ejemplo.

En la carpeta “expected” reside el fichero “cartridge-output.zip”
con el resultado esperado de la generación.
Herramientas para la generación de código
Propiedades de las metafachadas



Añadimos una propiedad a la metafachada que obtenga un
determinado valor etiquetado aplicado a la clase.
La propiedad se define como un atributo público frozen.
El valor etiquetado se define en el perfil UML:
...
<elementGroup name="Tagged Values">
<element name="VALOR_ETIQUETADO">
<value>@valor-etiquetado</value>
</element>
</elementGroup>
...
Herramientas para la generación de código
Propiedades de las metafachadas

Implementación del código manual:



La propiedad se llama “valor”.
Hay implementar el método “handleGetValor” en la clase
“PruebaFacadeLogicImpl”.
Para obtener el valor etiquetado:
return (String)this.findTaggedValue("@valor-etiquetado");

Plantilla:
#if ($clase.valor != 'null')
/**
* $clase.valor
*/
#end
class $clase.name {}
Herramientas para la generación de código
Restricciones en el metamodelo



Las restricciones se establecen sobre las
metafachadas en OCL.
Las restricciones son comprobadas en los
modelos que usen el cartucho.
Objetivo:

Definir la restricción de que la propiedad
“valor” no debe ser nula.
Herramientas para la generación de código
Definición de un perfil UML



Si el perfil UML es extenso, resulta cómodo que esté ya
definido para ser importando en el proyecto.
La definición y uso de perfiles depende de cada herramienta.
Una solución sencilla para MagicDraw es:




Crear un modelo vacío.
Definir un paquete con el nombre del perfil.
Incluir en ese paquete los estereotipos y valores etiquetados.
Para importar el perfil en otro modelo, en MagicDraw usamos
“Archivo/Importar Proyecto”.
Herramientas para la generación de código
Conclusiones

AndroMDA es un generador de código maduro que
genera código de calidad utilizando un proceso de
desarrollo bien definido.

Sin embargo, hay aspectos mejorables:






Soporte para más repositorios de modelos.
Transformaciones modelo-modelo.
Lenguajes de transformación modelo-código más allá de
Velocity o FreeMaker.
Mayor modularidad del proceso de transformación a
través de un motor de workflow.
Mejora del problema de la consistencia incremental.
Todas estas mejoras están siendo desarrolladas para la
nueva versión 4.
Herramientas para la generación de código
Recursos


General: http://www.andromda.org
Resumen aspectos destacados de la herramienta:


Desarrollo aplicaciones J2EE:


http://galaxy.andromda.org/docs-3.2/configuration.html
Introducción a las metafachadas:


Tutorial Timetracker (varias versiones)
Configuración de un proyecto:


http://galaxy.andromda.org/docs-3.2/contrib/birds-eye-view.html
http://galaxy.andromda.org/docs-3.2/andromda-metafacades/
Uso de los cartuchos

http://galaxy.andromda.org/docs-3.2/andromda-cartridges/
Herramientas para la generación de código
Recursos

Introducción Velocity:


Introducción a Maven:


http://maven.apache.org/guides/getting-started/
JMI UML 1.4:


http://velocity.apache.org/engine/devel/user-guide.html
http://galaxy.andromda.org/docs/jmi-uml1.4/
Metafachadas de UML:

http://team.andromda.org/docs/andromda-metafacades/andromda-umlmetafacades/andromda-metafacades-uml/apidocs/
Descargar

Proyecto DAMDA