Download Tutorial Acceleo Introducción Prerrequisitos

Document related concepts
no text concepts found
Transcript
Tutorial Acceleo
Introducción
Acceleo1 es actualmente una herramienta de generación para desarrollo dirigido
por modelos, logrando hacer transformaciones M2T (Model to Text). Al integrarse
a eclipse permite desarrollos rápidos en JEE, PHP y JSP, entre otros. Esta
herramienta funciona partiendo de un modelo y seleccionando un módulo que
define las transformaciones a realizar para la generación de código.
Ilustración 1 Funcionamiento de Acceleo
Se dará un pequeño tutorial con los pasos necesarios para realizar un proyecto
Acceleo y generar código.
Prerrequisitos
Para poder seguir este tutorial es necesario lo siguiente:

Eclipse Modeling Framework (EMF)- http://www.eclipse.org/modeling/emf/
Una vez descargado EMF se procede a instalar los componentes necesarios. Para
1
Página oficial de Acceleo. http://www.acceleo.org/pages/home/en
esto es necesario hacer click en el botón para instalar componentes de
modelamiento.
Una vez cargue la ventana de los diferentes componentes de modelamiento disponibles,
seleccionar el componente de Acceleo y proceder con la instalación.
Una vez terminada la instalación la herramienta le pedirá que la reinicie. Proceda a
reiniciar el IDE de Eclipse. Una vez vuelva a abrir eclipse, el plugin para el IDE con
Acceleo integrado estará disponible para su uso.
Creación del proyecto Acceleo
Para lograr un proyecto de Acceleo es necesario obtener tanto un modelo de entrada
como un folder de salida, en este caso podría ser tanto un diagrama de clases UML como
un modelo generado en un proyecto ATL, y un Java Project respectivamente.
El primer paso es usar la perspectiva Acceleo, que permitirá trabajar de una manera más
rápida. Cree un Acceleo Project que contendrá las definiciones de las transformaciones
que se quieren realizar a partir de un modelo. Haciendo Click derecho sobre el explorador
de paquetes, seleccione New > Acceleo Project.
Este proyecto puede llamarse como desee, para este tutorial se ha llamado
org.eclipse.acceleo.module.sample, presione Next.
Presione Browse para seleccionar el URI del metamodelo a usar, este paso no es
relevante el metamodelo que seleccione si se desea trabajar con un metamodelo
especifico generado en un proyecto ATL.
Presione Next y luego Finish. Se creara y abrirá un archivo generate.mtl sobre el que se
definirá el código a generar. El archivo generate.mtl describe el módulo de Acceleo, este
es quien define el código que se generara para una plataforma específica, que para este
estudio es Java. Este módulo, contiene una seria de plantillas que contienen las
características del código fuente que se desea generar a partir de un modelo. De hecho la
extensión mtl, hace referencia a model transformation languaje.
El archivo generate.mtl es el siguiente:
[comment encoding = UTF-8 /]
[module generate('http://www.eclipse.org/uml2/3.0.0/UML')/]
[template public generate(aClass : Class)]
[comment @main /]
[file (aClass.name, false, 'UTF-8')]
[aClass.name/]
[/file]
[/template]
El contenido del archivo generate.mtl debe ser reemplazado por el código que generara la
clase junto con sus atributos, ya que aunque en este momento ya se esta generando un
archivo de texto, aun no se han definido transformaciones. Reemplace el el contenido del
archivo con el siguiente código correspondiente a las transformaciones para generar el
código del kernel.
[comment encoding = UTF-8 /]
[module generate('/musicStore/input/mms/kernelMM.ecore')/]
[template public generate(c : Kernel )]
[comment @main /]
[file (c.system.element.name.toUpperFirst().concat('.java'), false)]
package org_eclipse_icesi_kernel;
public class [c.system.element.name.toUpperFirst()/] {
/**Conjunto de atributos de la clase [c.name/]
*/
[for (p: Attribute | c.system.element.attributes)]
private String [p.name/];
[/for]
/**Constructor de la clase [c.name/]
[for (p: Attribute | c.system.element.attributes)]
@param p[p.name/] valor del constructor
[/for]
*/
public [c.system.element.name.toUpperFirst()/]([for (p: Attribute |
c.system.element.attributes) separator(',')] String p[p.name/][/for]){
[for (p: Attribute | c.system.element.attributes)]
[p.name/] = p[p.name/];
[/for]
}
/**Constructor de la clase [c.name/] */
public [c.system.element.name.toUpperFirst()/](){
}
[for (p: Attribute | c.system.element.attributes) separator('\n')]
/**Metodo get[p.name.toUpperFirst()/] Permite obtener [p.name/]
@return String El valor para del atributo [p.name/]*/
public String get[p.name.toUpperFirst()/]() {
return this.[p.name/];
}
[/for]
[for (p: Attribute | c.system.element.attributes) separator('\n')]
/**Metodo set[p.name.toUpperFirst()/] Permite cambiar [p.name/]
@param String Nuevo valor para el atributo [p.name/]*/
public void set[p.name.toUpperFirst()/](String p[p.name/]) {
this.[p.name/] = p[p.name/];
}
[/for]
}
[/file]
[file (c.system.name.toUpperFirst().concat('.java'), false)]
package org_eclipse_icesi_kernel;
import
import
import
import
java.util.Observable;
java.util.ArrayList;
java.util.Iterator;
java.util.Arrays;
public class [c.system.name.toUpperFirst()/] extends Observable {
private ArrayList<[c.system.element.name.toUpperFirst()/]>
elements;
private [c.system.element.name.toUpperFirst()/] selectedElement;
private static [c.system.name.toUpperFirst()/] instance;
private [c.system.name.toUpperFirst()/]() {
this.selectedElement = null;
this.elements = new
ArrayList<[c.system.element.name.toUpperFirst()/]>();
}
public static [c.system.name.toUpperFirst()/] getInstance() {
if (instance == null) {
instance = new [c.system.name.toUpperFirst()/] ();
}
return instance;
}
public boolean add([c.system.element.name.toUpperFirst()/] value) {
boolean result = false;
if (findSongByID(value) == null) {
this.elements.add(value);
result = true;
}
setChanged();
notifyObservers();
return result;
}
public ArrayList<[c.system.element.name.toUpperFirst()/]>
getElements() {
ArrayList<[c.system.element.name.toUpperFirst()/]>
elementsCopy = new
ArrayList<[c.system.element.name.toUpperFirst()/]>(elements);
return elementsCopy;
}
public void
setSelectedElement([c.system.element.name.toUpperFirst()/]
selectedElement) {
this.selectedElement = selectedElement;
setChanged();
notifyObservers();
}
public [c.system.element.name.toUpperFirst()/] getSelectedElement()
{
return this.selectedElement;
}
public [c.system.element.name.toUpperFirst()/]
findSongByID([c.system.element.name.toUpperFirst()/] searchedElement) {
boolean found = false;
[c.system.element.name.toUpperFirst()/] element = null;
for (Iterator<[c.system.element.name.toUpperFirst()/]>
iterator = elements.iterator(); iterator.hasNext()
&& !found;) {
element = iterator.next();
if
(element.getName().equals(searchedElement.getName())) {
found = true;
}
}
if (!found) {
element = null;
}
return element;
}
[for (p: Attribute | c.system.element.attributes) separator('\n')]
public void bubbleSortBy[p.name.toUpperFirst()/]() {
[c.system.element.name.toUpperFirst()/]['[]'/] objects =
getElements().toArray(new
[c.system.element.name.toUpperFirst()/]['[elements.size()]'/]);
for (int i = 0; i < objects.length; i++) {
for (int j = i + 1; j < objects.length; j++) {
String
value_1=objects['[i]'/].get[p.name.toUpperFirst()/]()+"";
String
value_2=objects['[j]'/].get[p.name.toUpperFirst()/]()+"";
if (value_1.compareTo(value_2) > 0) {
swap(objects, i, j);
}
}
}
elements = new
ArrayList<[c.system.element.name.toUpperFirst()/]>(Arrays.asList(objects)
);
setChanged();
notifyObservers();
}
[/for]
private void swap(Object['[]'/] objects, int i, int j) {
Object temp = objects['[i]'/];
objects['[i]'/] = objects['[j]'/];
objects['[j]'/] = temp;
}
}
[/file]
[/template]
Si se tienen en cuenta las siguientes líneas, se esta usando en este modulo el
metamodelo del kernel que se encuentra en otro proyecto (ATL Project), y se define la
plantilla para realizar una transformacion M2T de el.
[module generate('/musicStore/input/mms/kernelMM.ecore')/]
[template public generate(c : Kernel )]
Se deben tener en mente ciertas cosas, entendiendo mejor el código usado.
Los Templates son un conjunto de sentencias usadas para generar texto.
[template public generate(c : Class)]
...
[/template].
La etiqueta File le dice al motor de Acceleo que debe generar el contenido del tag en un
archivo de texto.
[file(<uri_expression>, <append_mode>,
<outencoding>)]
(...)
[/file]
La etiqueta For para recorrer las colecciones.
[for (Sequence{1, 2, 3})
before ('sequence: ')
separator (', ')
after (';')]
[/for]
Las condiciones son escritas con la etiqueta If-else
[if (condition)]
...
[elseif (condition)]
...
[else]
...
[/if]
En el código que se debe copiar al archivo generate.mtl ya es evidente el código Acceleo
usado para generar los constructores, los atributos y métodos de la clase, que pueden ser
mucho más compresibles con la breve explicación anterior.
Se debe comprobar que en el archivo MANIFEST.MF contenga los siguientes plugins:







org.eclipse.emf.ecore
org.eclipse.emf.ecore
org.eclipse.emf.ecore.xmi
org.eclipse.ocl
org.eclipse.ocl.ecore
org.eclipse.acceleo.model
org.eclipse.acceleo.engine
Este archivo podría cambiar, dependiendo del metamodelo con el que se quiera trabajar,
en el caso de un metamodelo que definamos propiamente se deben tener los plugins
anteriores, pero si se desea trabajar por ejemplo, con el metamodelo UML se debe tener
el plugin adicional.

org.eclipse.uml2.uml
Se debe crear un proyecto Acceleo haciendo Click derecho sobre el explorador de
paquetes, seleccione New > Project, luego Java Project. Se puede nombre el nuevo
proyecto como se desee, en nuestro caso se ha llamado musicStore.
Para este momento ya se puede generar el código a partir del modelo UML que se creó,
que para efectos de esta explicación se hace de esta manera, aunque se puede recibir
como el resultado de transformaciones productos de un proyecto ATL.
Seleccionado el archivo generate.mtl, Click Derecho > Run as > Launch Acceleo
Application.
Se lanza una página de configuración en la que se determinara el modelo de entrada y el
folder de salida necesarios para ejecutar el proyecto Acceleo. La información debe ser
como se muestra a continuación de acuerdo a los datos del metamodelo de entrada y al
folder de salida para las transformaciones M2T.
Se pueden tener en cuenta ciertas elementos al momento de profundizar con el
trabajo de Acceleo.
Un módulo puede usar otros módulos al momento de su ejecución, por lo que se
debe usar una sentencia import en el archivo .mtl.
[ import
qualified::name::of::imported::module/]
XMI generado en ATL
XML (Extensible Markup Language), es un conjunto de reglas que definen unas
etiquetas semánticas, y que en el tema de la generación de código permiten que
se tome a los modelos de un específico, posteriormente llegando a código.
Ilustración 1 - Código XMI generado en ATL
De acuerdo a la ilustración 1, la etiqueta <system></system> hace referencia a la
clase
contenedora,
<element></element>
al
resto
de
clases,
<attributes></attributes> a los atributos de las clases y la etiqueta <sorts> a los
ordenamientos de cada uno de los atributos. Identificando estos elementos se
puede hacer fácilmente la transformación de modelo a texto, M2T, en Acceleo.
Ejercicio
A manera de ejercicio, se le pide que el código M2T para el método insertionSort.
Anexos
Para mayor información sobre Acceleo se recomienda visitar los siguientes sitios web:
http://www.obeonetwork.com/page/acceleo-user-guide
http://sistemas.uniandes.edu.co/~isis4712/dokuwiki/doku.php?id=tl_acceleo
http://wiki.eclipse.org/Acceleo/Quick_Start
www.dsic.upv.es/asignaturas/facultad/lsi/trabajos/192000.doc