sem02c-Plantillas-Velocity [Modo de compatibilidad]

Plantillas Velocity
María Consuelo Franky
[email protected]
Universidad Javeriana - 2010
1
Facilidade ofrecidas por Velocity
2
Facilidades ofrecidas por Velocity
✹
Permite hacer plantillas que sirven para generar :
◆ archivos fuentes en cualquier lenguaje (Java, C#, PHP, …)
◆ páginas web con contenido dinámico en cualquier tecnología
(JSP, ASP, JSF, …)
◆ descriptores XML
◆ scripts SQL
◆ etc.
✹
Permite hacer macros para extender los archivos
generados
◆ por ejemplo, extender el descriptor web.xml con con
referencias a nuevos EJBs
3
Elementos del lenguaje de plantillas Velocity
4
Un primer ejemplo
✹
Plantilla Velocity .vm para generar página web
dinámica
<html>
<body>
## This is a comment line.
#set( $foo = "Velocity" )
Hello $foo World!
</body>
</html>
◆ contiene
• un comentario Velocity en la línea con ##
• una referencia a una variable Velocity llamada $foo
(o también la notación ${foo}
)
• una directiva #set que le da valor a la variable
• uso de la variable $foo dentro del texto en donde será
reemplazada por su valor
5
Tipos de referencias
✹
Variables (velocity): $Identifier
o en notación larga: ${Identifier}
✹
Propiedades: $Ident1.Ident2
o ${Ident1.Ident2}
✹
Métodos: $Ident1.Ident2( ..)
o ${Ident1.Ident2( ..)}
◆ ej: $sun.getPlanet(["Earth", "Mars] )
6
Directiva set: da valor a una referencia
✹
Puede darle valor a referencia variable simple:
#set( $primate = "monkey" )
◆ o variable lista:
#set( $greatlakes =
["Superior","Michigan","Huron","Erie","Ontario"])
✹
Puede darle valor a referencia propiedad:
#set( $customer.Behavior = $primate )
✹
Alternativas para el valor asignado:
◆
◆
◆
◆
◆
◆
Variable reference
String literal
Property reference
Method reference
Number literal
ArrayList
7
Directiva if: generar texto según condiciones
✹
Generar un texto solo si una variable Velocity es
verdadera o diferente de null:
#if( $foo )
mi texto 1!
continuacion texto 1
#end
✹
Varias alternativas de generación de texto según
condiciones:
#if( $foo1 )
mi texto 1!
continuacion texto 1
#elseif( $foo2 )
mi texto 2!
#else
mi texto 3!
#end
8
Directiva for: generar texto para cada elemento
de una lista
✹
Ciclo que recorre una lista Velocity y generar texto
para cada elemento:
#foreach( $product in $allProducts )
texto para $product
#end
◆ $allProducts es una variable Velocity de tipo Vector,
Hashtable o Array, $product es variable auxiliar para referirse
a un elemento
◆ en cada ciclo se incremente el contador $velocityCount
(desde 1)
✹
Ejemplo de página JSP incluyendo el contador de
Velocity en los textos generados:
<table>
#foreach( $customer in $customerList )
<tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end
</table>
9
macros Velocity: permiten factorizar textos a
generar
✹
La definición de una macro le da nombre y
opcionalmente parámetros:
#macro( tablerows $color $somelist )
#foreach( $element in $somelist )
<tr><td bgcolor=$color>$element</td></tr>
#end
#end
✹
Al usar una macro desde una plantilla se debe
indicar el valor de los parámetros:
#set( $greatlakes =
["Superior","Michigan","Huron","Erie","Ontario"] )
#set( $color = "blue" )
<table>
#tablerows( $color $greatlakes )
10
</table>
✹
Los argumentos de las macros pueden ser de los
siguientes tipos:
◆
◆
◆
◆
◆
◆
◆
✹
Reference : anything that starts with '$'
String literal : something like "$foo" or 'hello'
Number literal : 1, 2 etc
IntegerRange : [ 1..2] or [$foo .. $bar]
ObjectArray : [ "a", "b", "c"]
boolean value true
boolean value false
Los parámetros son pasados por nombre:
◆ significa que el texto valor de la macro es generado de nuevo
cada vez que se invoca
11
Otras directivas
✹
#include : permite incluir un archivo de texto
✹
#parse : importa otra plantilla Velocity
◆ puede haber recursión
✹
#stop : detiene el procesador Veloctiy
✹
#break: detiene la actual directiva
✹
#evaluate: evalúa dinámicamente una referencia
✹
#define: asignar un bloque a una referencia
12
Uso básico de Velocity desde Java
13
Pasos para usar Velocity desde Java
1.
Inicializar Velocity
2.
Crear el contexto de Velocity
3.
Añadir objetos datos al contexto
4.
Seleccionar un template Velocity
5.
Mezclar el template con los objetos datos para
obtener el texto resultante.
14
Código básico Java para usar Velocity
// 1- Inicializar Velocity
Velocity.init();
// 2- crear contexto Velocity
VelocityContext context = new VelocityContext();
// 3- poner objetos datos en el contexto
context.put( "name", new String("Velocity") );
Template template = null;
try{
// 4- seleccionar un template Velocity
template = Velocity.getTemplate("mytemplate.vm");
}
catch( ResourceNotFoundException rnfe ){
// couldn't find the template
}
catch( ParseErrorException pee ){
// syntax error : problem parsing the template
}
catch( Exception e ){ . . . }
StringWriter sw = new StringWriter();
// 5- mezclar el template con los objetos datos
template.merge( context, sw );
15
Cómo se usa Velocity en el framework
CincoSOFT
16
Elementos que constituyen
el framework de generación
✹
Generadores contemplados en el framework
CincoSOFT
◆
◆
◆
◆
◆
◆
✹
generador del esqueleto del sistema
generador del EJB de seguridad
generador del módulo de seguridad
generador de un EJB
generador de un módulo
generador de un caso de uso
Cada generador:
◆ utiliza un conjunto de plantillas y macros
◆ utiliza un archivo de propiedades para darle valor a un conjunto
de variables Velocity que aparecen en sus plantillas
◆ genera archivos fuentes de diversos tipos bajo el directorio del
proyecto destino: fuentes Java, páginas, descriptores XML, ant,
css, etc.
17
Plantillas Velocity correspondientes a una
aplicación Java EE
✹
Organización genérica de plantillas
◆ Plantillas organizadas en subdirectorios correspondientes a los
de una aplicación general (fuentes, páginas, etc.)
◆ paquete genérico com.project y nombres genéricos (por ejemplo
Xxx para referirse a un EJB
✹
Toda plantilla da valor a la variable $path
◆ ruta en donde debe quedar el archivo generado
◆ ejemplo: ruta para la clase de un EJB:}
#set( $path =
"${javasrc}/com/${project}/component/${Ejb}/ejb")
✹
C/ generador tiene un conjunto de variables Velocity
que usa el conjunto de plantillas asociadas
◆ ejemplo: el generador de un EJB utiliza las plantillas Xxx.vm,
XxxHome.vm, XxxEJB.vm, XxxDAO.vm dentro de las cuales
utiliza las variables ${Ejb}, ${project}, ${module},etc.
18
Archivo de propiedades para un generador
✹
Ejemplo: EJBsession.properties
◆ propiedades para el generador de un EJB
# name of velocity log file in current directory
runtime.log = logs/velocity_EJBsession.log
# paths of directories where the templates are located:
file.resource.loader.path =
../../macros,../../javasrc/com/project/component/xxx/ejb
# name of the project in lower case:
project = acmesimple
# absolute root path of files to be generated:
root = C:/ws-eclipsejee-3.4.2/acmesimple
# path of java files, relative to root:
javasrc = src
# path of pages, relative to root:
defaultroot = defaultroot
# name of the ejb, in lower case :
ejb = acmesimple
# server type: weblogic, jboss:
serverType =jboss
19
Procesador Velocity para un generador
✹
Inicializar Velocity (ejemplo: generador de un EJB)
◆
◆
indicando archivo de propiedades
extrayendo las propiedades y construyendo nuevas
String path = ../properties
String propertiesFile = "EJBsession.properties";
Velocity.init(path + "/" + propertiesFile);
String project =
(String)Velocity.getProperty("project");
String Project = project.substring(0,1).toUpperCase() +
project.substring(1);
String root = (String)Velocity.getProperty("root");
String ejb = (String)Velocity.getProperty("ejb");
String Ejb = ejb.substring(0,1).toUpperCase() +
ejb.substring(1);
String serverType =
(String)Velocity.getProperty("serverType");
. . .
20
✹
Crear el contexto Velocity
◆
colocando en el contexto las variables correspondientes a las
propiedades
context = new VelocityContext();
context.put("project", project);
context.put("Project", Project);
context.put("root", root);
context.put("ejb", ejb);
context.put("Ejb", Ejb);
context.put("serverType", serverType);
...
21
✹
Procesar las plantillas del generador produciendo
archivos en el proyecto destino
◆
se generan los archivos fuentes en el proyecto destino ubicado
en la ruta indicada por la propiedad root y con el path relativo
indicado por la variable $path que establece cada plantilla
util = new UtilsVelocity(context, root, Project);
util.processTemplate("Xxx",
util.processTemplate("XxxHome",
util.processTemplate("XxxEJB",
util.processTemplate("XxxDAO",
Ejb
Ejb
Ejb
Ejb
+
+
+
+
".java");
"Home.java");
"EJB.java");
"DAO.java");
...
22
◆
procesar una plantilla (clase UtilsVelocity)
public String processTemplate (String filePrefix,
String outputFileName) {
. . .
// obtener la plantilla:
Template template
= Velocity.getTemplate(filePrefix + ".vm");
// reemplazar en la plantilla variables
// por valores del contexto:
StringWriter sw = new StringWriter();
template.merge(context, sw);
// grabar el texto obtenido en el archivo destino
File outdir = new File(root, path);
outdir.mkdirs();
FileWriter writer = new FileWriter
(root + "/" + path + "/" + outputFileName);
writer.write(sw.toString());
. . .
}
23
✹
Extender archivos existentes en el proyecto destino
mediante macros
◆
un archivo a extender contiene en comentario invocación a una macro
<application>
<display-name>acme</display-name>
<description>acme Application: full system
</description>
<!-#section_application_ejb()
-->
. . .
◆
la macro reemplaza la linea central del comentario por un texto
más un nuevo comentario que invoca la macro:
#set( $path = "${defaultroot}/META-INF")
#macro (section_application_ejb)
section for ${Ejb} ejb
-->
<module>
<ejb>${Ejb}_ejb.jar</ejb>
</module>
<!-\#section_application_ejb()
#end
24
◆
procesador Velocity: procesar una macro
// obtiene la macro y resuelve sus variables Velocity
// con el valor de propiedades puestas en el contexto
util.getMacro("macro-section-application_ejb");
// coloca en un subdirectorio de plantillas el archivo
// a extender (a manera de plantilla)
outputText = util.textOfFile("application.xml");
util.copyToGenerated("applicationGlobal_Gen",
outputText);
// procesa la plantilla del archivo a extender que
// tiene la invocacion a la macro
util.processTemplate("applicationGlobal_Gen",
"application.xml");
...
25
tratamiento de las propiedades que son listas
✹
Ejemplo: en el archivo de propiedades
# list of ejbs used by the module:
listEJB = Contratos,Security
✹
Plantilla que usa la lista
. . .
#foreach ($nameEJB in $listEJB)
import
com.${project}.component.${nameEJB}.ejb.${nameEJB};
#end
✹
Captura en el procesador Velocity
private Vector listEJB =
(Vector)Velocity.getProperty("listEJB");
. . .
context.put("listEJB", listEJB);
26
Otros lenguajes de plantillas:
Jelly: http://apt-jelly.sourceforge.net/
FTL - FreeMarker Template Language: lo usa el
generador JBoss Seam: http://fmpp.sourceforge.net
27