Velocity es un proyecto de Apache para el desarrollo de Templates para la capa de vista dentro del modelo MVC, siendo esta última la más conocida de todas las formas de uso de Velocity. Pero es mucho más que eso, podemos usar el motor de Velocity para lo que necesitemos utilizando siempre el concepto de uso de templates.
¿Que es un template?
Como su nombre lo dice es una plantilla, les dejo un ejemplo de como seria una plantilla Velocity para una vista en html:
1 2 3 4 5 6 7
#set ($hola = "Hola Mundo") <h1>$hola</h1>
## Esto es una macro de Velocity #d()
<h2>$salida</h2>
Donde:
#set es una directiva para settear valores
$hola es la variable setteada con el valor Hola Mundo
#d() es una Velocimacro
$salida es una variable de contexto que sera setteada desde la ejecución de Velocity (ver código fuente de java)
¿Cuándo podemos utilizar Templates?
Hay un sin número de aplicaciones, como por ejemplo:
Envío de mails personalizados, en este punto uno podría escribir los templates (email tipo) y dejar ciertos tags de Velocity (llamados directivas) para la personalización.
Generar XML’s dinamicos.
Generar otro tipo de salidas como por ejemplo JSON.
Generar PDF mediante docbook, incluso otro tipo de archivos (rdf, txt)
Y el más usado, escribir templates para ser usados como html en la capa de vista.
Usando Velocity Engine
Primero creamos un proyecto con Maven2 para hacer la vida mas fácil y agregamos las siguientes dependencias:
// Carga archivo de propiedades de velocity prop.load(getClass() .getResourceAsStream("/velocity.properties"));
// Inicializa Velocity Velocity.init(prop);
_ctx = newVelocityContext(); }
public String mergeTemplate()throws ResourceNotFoundException, ParseErrorException, Exception {
init();
// Carga el template Templatetpl= Velocity.getTemplate("template.vm");
// Agrega una variable al contexto luego puede ser usada // como $salida _ctx.put("salida", "OK");
// Creo un Writer para almacenar la salida Writerwriter=newStringWriter();
// Genero la mezcla del template con sus las variables // del contexto y macros de velocity tpl.merge(_ctx, writer);
// Finalmente genero un string con la salida return writer.toString(); } }
Espero que el código se explique por si solo.
Aquí dejo el ejemplo completo hecho con Maven2, para ver la ejecución, dentro del código fuente va un Test Unitario que imprime la salida de los templates.
groupId: Es el package de referencia de tu aplicación.
artifactId: Es el nombre de tu aplicación (en maven se le llama artefacto)
Maven creará un directorio con el nombre del artefacto (aplicación), en este caso validate y la estructura de directorio quedará de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 11 12 13
. |-- pom.xml `-- src |-- main | `-- java | `-- com | `-- firefox | `-- App.java `-- test `-- java `-- com `-- firefox `-- AppTest.java
Con esto queda lista la estructura básica de tu aplicación Java. En la estructura de directorios se pueden fijar que existen dos source folder el main y el de test. Además existe un archivo llamado pom.xml que nos permitirá administrar nuestro proyecto java, gestionar las dependencias del proyecto, generar el sitio web del proyecto al estilo maven o simplemente tareas simples como compilar, empaquetar o correr test unitarios. Estas acciones o tareas son llamadas goals.
Algunas tareas simples (goals)
1
$ mvn compile
Esta acción lo que hace es compilar el proyecto dejando los binarios en el directorio target del proyecto de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
. |-- pom.xml |-- src | |-- main | | `-- java | | `-- com | | `-- firefox | | `-- App.java | `-- test | `-- java | `-- com | `-- firefox | `-- AppTest.java `-- target `-- classes `-- com `-- firefox `-- App.class
1
$ mvn clean
Limpia el proyecto, es decir, eliminar los compilados. Esta acción eliminará todas las clases compiladas ubicadas en el directorio target dentro del proyecto, este directorio es similar a los directorios build o bin que genera eclipse o netbean.
1
$ mvn package
Como su nombre lo dice, esta acción empaqueta la aplicación y deja el paquete en el directorio target.
1
$ mvn test
Esta acción corre los test unitarios guardados en el source folder de los tests.
Para que los test puedan correr, estos deben extender de TestCase de JUnit. Además los nombres de las clases deben seguir un estándar para su ejecución.
Los nombres de las clases del tipo test deben terminar en Test, por ejemplo: ClientTest
Dentro de la clase ClientTest deben existir métodos que hagan los test. Estos métodos deben ser public y ademas empezar con la palabra test.
Dentro de los métodos puedes utilizar los assert para verificar la correcta ejecución del test unitario. Los assert son como su palabra lo dice aciertos, el método te pide como argumentos lo que tu esperas y lo que finalmente te devuelve la ejecucion del test. Si ambos resutados coinciden el test se ejecuta con resultado exitoso. También está la posibilidad de que los resultados sean distintos y en realidad es lo que tu esperas (que sean distintos) para que el test sea exitoso. Un pequeño ejemplo:
Este ejemplo sale con un assert en true, es decir, se ejecuta con resultado exitoso. Es lo que se espera del test.
1
$mvn site
Esta acción te permite generar un sitio web estático con información referente al proyecto que estas realizando. La información que necesita para poder crear el sitio es referente al archivo **pom.xml **(más adelante hablaré de este archivo).
El sitio generado lo dejará en un directorio llamado site dentro del **target **, donde encontrarás un index.html que podras ver con tu navegador favorito (espero que sea firefox).
1
$mvn install
Esta acción compila, empaqueta e instala tu proyecto en un repositorio local de maven (generalmente se encuentra en ~/.m2/repository) . De esta forma puedes utilizar ese proyecto dentro de otro agregándolo como dependencia en el archivo pom.xml. Hay que tener como consideración que los proyectos instalados deben ser bien versionados.
1
$mvn eclipse:eclipse
Con esta acción puedes agregar los archivos necesarios para que puedas convertir un proyecto maven en un proyecto maven+eclipse. En lo posible ojalá puedas instalar el plugin de maven para eclipse.
Existen un montón de acciones (goals) más que funcionan con plugins de maven y que complementan algunas otras tareas.
Como verán maven hace muchas tareas tediosas en simples pasos que además te ayudan a optimizar tiempos de desarrollo, integraciones rápidas, actualización de librerías y documentación de tu proyecto.
En esta serie de artículos pretendo explicar el funcionamiento a grandes rasgos de Maven.
Primero… ¿ qué es Maven y para qué sirve ?
Maven es una herramienta para la gestión de proyectos java desde el lado del desarrollador, es decir, un automatizador de tareas al estilo de ant task. Más adelante veremos las cosas que puede hacer con mas detalle, pero entre las actividades diarias que hace de un desarrollador java están:
compilar
correr test unitarios
empaquetar
levantar webserver o application server
manejo de dependencias del proyecto
Instalando Maven
Primero debes descargar el binario de maven desde su pagina oficial.
Debes descomprimir el archivo y guardarlo en un directorio conocido.
Luego debes agregar al PATH el directorio bin para que puedas ejecutar maven.
A veces es muy recomendable agregar en el script que ejecuta maven el JAVA_HOME, asi maven no se confunde de java si es que tienen varias JVM instaladas.
Editar el siguiente archivo /home/usuario/maven/bin/mvn:
1 2 3 4 5 6 7 8 9
# ------------------------------------------ # Maven2 Start Up Batch script # # Required ENV vars: # ------------------ # JAVA_HOME - location of a JDK home dir # export JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun
También puedes configurar tu JVM por defecto de la siguiente manera en ubuntu/debian:
1 2 3 4 5 6 7 8
# update-alternatives --config java Hay 2 alternativas que proveen `java'. Selección Alternativa ----------------------------------------------- 1 /usr/bin/gij-4.2 *+ 2 /usr/lib/jvm/java-1.5.0-sun/jre/bin/java Pulse <Intro> para mantener el valor por omisión [*] o pulse un número de selección:
Así funciona Struts2 para una petición del tipo Request:
Llega un Request a la aplicación.
El Request es interpretador por el DispatcherFilter y determina que Action y que conjunto de Interceptors invocar.
Cada Interceptor ejecuta sus acciones previas a la ejecución del método de Action a invocar.
Si el Interceptor I18nInterceptor intercepta el Action: Se ubicará en la sesión del usuario un objeto Locale para utilizar i18n.
Si el Interceptor ValidationInterceptor intercepta el Action: Se ejecutan la reglas de validación definidas sobre el Action
Si el Interceptor AnnotationValidationInterceptor intercepta el Action: Se chequea en el método a invocar del Action si tiene la anotación @SkipValidation, en cuyo caso no se realizan validaciones
Es ejecutado el método anotado con @Before en el Action
Es invocado el método del Action.
Es ejecutado el método anotado con @After en el Action
Es ejecutado el método anotado con @BeforeResult en el Action
Cada Interceptor ejecuta sus acciones posteriores a la ejecución del método de Action a invocar
Si el Interceptor ModelDrivenInterceptor intercepta el Action: Luego de la ejecución del Action se ubicara en el value stack el modelo que provee el Action.
Si el Interceptor ParametersInterceptor intercepta elAction: Los parametros provenientes del Request se ubican en el value stack
Se examina el resultado obtenido del Action y se determina el Result correspondiente.
Mediante el Result determinado se genera la vista, y según la configuración definida sober el se invoca el proceso de generación de la vista.
La semana pasada he estado programando duro para un proyecto que tengo en la USACH, y que requería de estar cambiándome de ventana en ventana, estar mirando planos y diagramas de procesos y a eso sumar la ventana donde estoy metiendo el código… resultado: cansancio, desconcentración y poca eficiencia.
Para solucionar el problema… no me quedo otra que invertir… y se arreglaron todos los problemas, ahora tengo dos monitores trabajando, mi viejito Samsung SyncMaster 753DFX y el juguete nuevo un ViewSonic VX715 TFT de 17’’ una maravilla de la tecnología…
Ademas de ver mejor… jaja … he estado optimizando mis códigos antiguos de PHP, que por decir lo menos, están bien desordenados y poco estandarizados. Así que empece a programar algunas cosas con Orientación a Objetos para reutilizar códigos, ordenar código y para que se vea más bonito y legible.
Me recuerdo que hace tiempo había probado PHPEclipse y la verdad… no servia para nada, era casi un notepad o un editor de texto rasca. Me baje la ultima version de este plugins para Eclipse y me lleve una grata impresión, hace todo lo que en ese entonces quería que hiciera, como por ejemplo… autocompletar código, estructurar las clases y sus métodos y algo que siempre es bienvenido como el autoformateo del código escrito.
Ayer me quede hasta tarde tratando de hacer varias cosas que al final… solo una me resulto y mas o menos.
Empece el dia con el proyecto de Firefox Chile, me baje los fuentes de Firefox1.0 y me di la lata de leerme el documento para la construcción del fuente (build) en un instalador. Bueno primero… solucionar todo el entorno para la compilación, instalación de librerías básicas y una que otra aplicación de autotools. Aun así no pude encontrar en que paquete viene “gmake” para Debian (si saben me avisan). Bueno, leí por ahí algunos documentos de que se podía hacer con “make” asi que me animé y empece a leerme el README donde salen las instrucciones de como hacerlo además del documento de Mozilla Developers, el único cambio… donde dice gmake cambiarlo por make :D
El compu estuvo trabajando un buen rato compilando y lo hace súper bien, luego viene la parte densa que no entendí. Cuando quieres hacer el “make install”, ahi toma los compilados y los pasa al directorio que le diste en:
1
./configure --prefix=/home/pcollaog/firefox_test
Bueno la verdad es que pasa una colección de archivos compilados a dicho directorio pero de ahí… no se que más hacer. Me falta harto aún :( pero siento que estoy cada vez mas cerca. Por lo menos la vez pasada no salí del ./configure ahora ya compila :D
En la tardecita… luego de varios intentos fallidos de la compilación de FF, me metí en otro tema para el proyecto, la habilitación de un CVS para los que trabajamos en este proyecto de la localización de FF. Todo bien para los usuarios del sistema, pero me aviso un miembro del Team que no tenía acceso al CVS, ahi me di cuenta que los usuarios que no son del sistema tenían problemas para entrar al cvs, empece a investigar porque y entendí porque no podían entrar. Tenia que asociar a los usuarios de NOsistema a uno del sistema, asi que cree un Grupo de usuarios CVS y un usuario del CVS. Luego asocie en el archivo passwd a los usuarios de NOsistema al usuario CVS. Luego unos cuantos chmod y chown para cambiar los atributos, propietarios y derechos de los directorios… andando :D. Un poco mas tarde se me ocurrió ver el repositorio por web y todo mal… con los cambios de los chown y chmod el CVSWEB dejó de funcionar, asi que otra vez… hartos chown y chmod para encontrar la funcionalidad entre CVS y CVSWEB.
Más tarde (01:00 aprox) me anime a instalar MONO, empece a buscar algún repositorio de Mono para Debian… no había ninguno oficial y los que habían no funcionaban, parece que el proyecto de Mono4Debian anda medio flaco. Asi que me anime a bajar los fuentes y compilar mono. Para el primer archivos de fuentes mono-1.0.5.tar.gz funcionó todo ¡de pelos! compilo sin ningún problema. Luego hice mi primer “hola mundo” y ahi murió todo. Les voy a copiar el código para que lo vean y me corrijan si ven algún error: