04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de...

296
openFWPA Internacional openFWPA Manual de configuración de openFWPA (ManualConfiguración_openFWPA_20111230_v1.0)

Transcript of 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de...

Page 1: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

openFWPA Internacional

openFWPA

Manual de configuración de openFWPA (ManualConfiguración_openFWPA_20111230_v1.0)

Page 2: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 2 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

ÍNDICE 1. Control del documento..........................................................................................................................8

1.1. Información general .......................................................................................................................8 1.2. Histórico de revisiones...................................................................................................................8 1.3. Estado del documento ....................................................................................................................8

2. Introducción ..........................................................................................................................................9 3. Desarrollo de aplicaciones ....................................................................................................................9

3.1. Estructura de directorios ..............................................................................................................10 3.2. Compilación y despliegue del sistema .........................................................................................10 3.3. Pruebas unitarias ..........................................................................................................................11

4. Sistema de Logging (log4j).................................................................................................................12 4.1. Loggers.........................................................................................................................................13 4.2. Appenders ....................................................................................................................................14 4.3. Layouts.........................................................................................................................................15 4.4. Configuración...............................................................................................................................15

4.4.1. Ejemplo de configuración .....................................................................................................19 4.5. Componentes del openFWPA para Logging ...............................................................................23

4.5.1. LoggingManager...................................................................................................................23 4.5.2. PrincastHTMLLayout ...........................................................................................................25 4.5.3. Pistas de auditoría .................................................................................................................25 4.5.4. Pistas de rendimiento ............................................................................................................26

5. Spring ..................................................................................................................................................27 5.1. Spring en openFWPA ..................................................................................................................28 5.2. Estableciendo el datasource .........................................................................................................32 5.3. Enlazando con los DAOs .............................................................................................................35 5.4. Enlazando con los Manager .........................................................................................................36

5.4.1. Gestión de transacciones.......................................................................................................38 5.5. Enlazando con los Delegate .........................................................................................................40 5.6. Enlazando con los Actions...........................................................................................................40

6. Capa de acceso a datos........................................................................................................................41 6.1. Alternativas para implementar la capa de acceso a datos ............................................................42 6.2. ¿Qué es iBATIS? .........................................................................................................................43

6.2.1. iBATIS en openFWPA .........................................................................................................44 6.3. Pool de conexiones.......................................................................................................................51

6.3.1. Datasource en Apache Tomcat .............................................................................................54

Page 3: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 3 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

6.4. Pruebas unitarias ..........................................................................................................................55 6.4.1. Convenciones a seguir ..........................................................................................................56 6.4.2. Pruebas unitarias de objetos que acceden a bases de datos...................................................57

6.4.2.1. Pruebas unitarias de DAOs ............................................................................................60 6.4.2.2. Más información sobre la implementación de pruebas unitarias ...................................63

7. Capa de negocio ..................................................................................................................................64 7.1. Business Managers.......................................................................................................................64

7.1.1. Prueba unitaria sobre la capa Manager .................................................................................66 7.2. Business Delegate ........................................................................................................................71

8. Controlador .........................................................................................................................................76 8.1. web.xml........................................................................................................................................78 8.2. Declaración de las Actions...........................................................................................................86 8.3. Jerarquía de Actions.....................................................................................................................90

8.3.1. Clase PrincastAction .............................................................................................................92 8.3.1.1. Creando un error en una PrincastAction ........................................................................94 8.3.1.2. Creando un mensaje de advertencia en una PrincastAction ..........................................95 8.3.1.3. Modificando una redirección .........................................................................................96 8.3.1.4. Almacenamiento interno de una Action .........................................................................97 8.3.1.5. Interrupción de la maquinaria de estados de la Action ................................................100

8.3.1.5.1. Paginación sin reejecución de la lógica de negocio..............................................100 8.3.2. Diferentes tipos de PrincastAction......................................................................................101

8.3.2.1. Implementaciones concretas ........................................................................................101 8.3.2.1.1. PrincastExistAttributeAction ................................................................................101 8.3.2.1.2. PrincastRemoveAttributeAction ...........................................................................101 8.3.2.1.3. PrincastForwardAction .........................................................................................102 8.3.2.1.4. PrincastParameterAction.......................................................................................102

8.3.2.2. Actions Compuestas (Dispatch)...................................................................................103 8.3.2.2.1. PrincastDispatchAction.........................................................................................103 8.3.2.2.2. PrincastLookupDispatchAction ............................................................................108 8.3.2.2.3. PrincastCRUDAction............................................................................................110

8.3.2.2.3.1. Validación de Formularios en acciones compuestas......................................112 8.3.2.2.4. Actions para Listados............................................................................................113

8.3.2.2.4.1. PrincastListAction..........................................................................................114 8.3.2.2.4.2. PrincastPDFReportAction..............................................................................114 8.3.2.2.4.3. PrincastDispatchPDFReportAction ...............................................................116 8.3.2.2.4.4. PrincastXMLAction .......................................................................................116 8.3.2.2.4.5. PrincastDispatchXMLAction.........................................................................119

8.4. Action Forms..............................................................................................................................119 8.4.1. Validación de formularios...................................................................................................124

8.4.1.1. Validaciones de openFWPA ........................................................................................126

Page 4: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 4 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.4.1.2. Implementación de validadores ...................................................................................128 8.5. Mapeo en el fichero struts-config.xml .......................................................................................130

9. La vista ..............................................................................................................................................140 9.1. Hojas de estilo (CSS) .................................................................................................................140

9.1.1. Hojas de estilo en la aplicación de ejemplo ........................................................................140 9.2. Composición de las páginas JSP (vistas) ...................................................................................145 9.3. Pantalla de error .........................................................................................................................154 9.4. Tablas de paginación..................................................................................................................155 9.5. Creación de menús .....................................................................................................................161

9.5.1. Información general ............................................................................................................161 9.5.2. Definir los menús ................................................................................................................163 9.5.3. Displayers específicos de openFWPA ................................................................................167 9.5.4. Enlaces en los menús ..........................................................................................................168 9.5.5. Integración de Struts-menu con una aplicación Struts........................................................169 9.5.6. La librería de tags struts-menu-el.tld ..................................................................................171 9.5.7. Uso de la librería de tags en la página menu.jsp.................................................................171 9.5.8. Recursos utilizados por el displayer PrincastTabbedMenu ................................................172 9.5.9. Forwards a entradas de menú..............................................................................................175 9.5.10. Enlaces con parámetros dinámicos ...................................................................................176

9.6. Internacionalización ...................................................................................................................176 9.7. View Helpers, View Adapters, Acciones...................................................................................177 9.8. Accesibilidad..............................................................................................................................179 9.9. Librería de etiquetas para el diseño de interfaces de usuario (UI).............................................180

9.9.1. Selección de fechas y calendarios.......................................................................................183 9.9.1.1. Etiqueta <date:calendar/> ............................................................................................183 9.9.1.2. Configuración del calendario .......................................................................................184 9.9.1.3. Escribir la fecha actual .................................................................................................185

9.9.2. Barra de navegación............................................................................................................186 9.9.2.1. Generar una barra de navegación.................................................................................187

9.9.3. Etiquetas para componentes gráficos ..................................................................................188 9.9.3.1. Etiqueta para renderizar Paneles de Componentes para la UI (similares a los fieldset de HTML) ......................................................................................................................................189 9.9.3.2. Etiqueta para renderiza el caption o título de las etiquetas panel ................................190 9.9.3.3. Etiqueta para generar el bloque central de información de una página con un borde superior y otro inferior ..............................................................................................................191 9.9.3.4. Etiqueta para renderizar el caption o título de las etiquetas box..................................192 9.9.3.5. Etiqueta para renderizar un bloque en área determinada de la página sin aspecto visual...................................................................................................................................................193 9.9.3.6. Etiqueta para renderizar elementos de bloque de tipo fila ...........................................194 9.9.3.7. Etiqueta para renderizar elementos de bloque de tipo columna...................................194

Page 5: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 5 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

9.9.4. Notificación de errores <ui:errors>.....................................................................................196 9.9.5. Etiquetas de utilidad y propósito general ............................................................................196

9.9.5.1. Etiqueta para ocultar o mostrar código en función de un objeto .................................196 9.9.5.2. Etiqueta para generar código en función del rol de usuario (coincidencia).................197 9.9.5.3. Etiqueta para generar código en función del rol de usuario (no coincidencia)............198 9.9.5.4. Etiqueta para generar código de combos relacionadas entre si....................................198 9.9.5.5. Etiqueta para generar código para incluir los js utilizados en DWR ...........................200

10. Sistema de Inicialización y Arranque .............................................................................................201 10.1. Declaración de objetos inicializables.......................................................................................202

10.1.1. Variables ${…} en el fichero de inicialización ................................................................205 10.2. Desarrollo de objetos inicializables .........................................................................................206 10.3. Arranque de aplicaciones Web ................................................................................................207 10.4. Arranque manual......................................................................................................................207

11. Sistema de configuración de aplicaciones ......................................................................................208 11.1. Implementación de los objetos configurables ..........................................................................210

11.1.1. Implementando el interface Configurable.........................................................................210 11.1.1.1. Conjunto de Parámetros de Configuración (ConfigurationParameters) ....................210 11.1.1.2. Eventos de Configuración (ConfigurationEvent) ......................................................211

11.1.2. Registro de un objeto en el FrameworkConfigurator........................................................212 11.1.3. Ejemplo de clase que implementa la interfaz Configurable .............................................213

11.2. Plugins de configuración..........................................................................................................214 11.2.1. Añadir un plugin de configuración ...................................................................................214

11.2.1.1. Declaración de plugins en el fichero de inicialización ..............................................215 11.2.1.2. Plugins en openFWPA...............................................................................................217

11.2.1.2.1. Plugins basados en Properties .............................................................................218 11.2.1.2.2. Plugins basados en XML ....................................................................................219

12. Filtros Web......................................................................................................................................225 12.1. Filtros de openFWPA. PrincastFilter .......................................................................................225

12.1.1. Implementación de un nuevo filtro ...................................................................................226 12.1.2. Gestión de los filtros de forma dinámica ..........................................................................229 12.1.3. Filtros activables por reglas ..............................................................................................229

12.2. Configuración del filtro SecurityFilter.....................................................................................230 12.3. Filtro de navegación.................................................................................................................230 12.4. Filtros de Activación................................................................................................................231

12.4.1. Filtro de Temporalidad......................................................................................................232 13. Excepciones ....................................................................................................................................233

13.1. Loggeo de las Excepciones en los DAO..................................................................................234 13.2. Excepciones durante el proceso de autenticación ....................................................................235

14. Informes ..........................................................................................................................................238 14.1. Creación de diseños XML........................................................................................................239

Page 6: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 6 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

14.2. La herramienta iReports...........................................................................................................240 14.2.1. Visión general de la Interfaz .............................................................................................241 14.2.2. Compilar y establecer programas externos .......................................................................241 14.2.3. Nuevo informe con iReports .............................................................................................244 14.2.4. Parametros en iReport .......................................................................................................246 14.2.5. Fields.................................................................................................................................247 14.2.6. Variables ...........................................................................................................................247

14.3. Clases del OpenFWPA para la renderización de informes ......................................................248 14.3.1. Informes simples ...............................................................................................................248 14.3.2. Multi Reports ....................................................................................................................250

14.3.2.1. Forma de actuar:.........................................................................................................250 14.3.3. Las fuentes de datos de los informes. ...............................................................................250 14.3.4. Utilizando JasperReports en Linux / Unix sin X11. .........................................................250 14.3.5. Clase para la generación de tablas en PDF. ......................................................................250

14.4. Ejemplo de creación de infome con openFWPA.....................................................................251 14.4.1. Diseñar con iReports y obtener XML...............................................................................251 14.4.2. Guardar el XML................................................................................................................254 14.4.3. Compilación ......................................................................................................................255 14.4.4. Crear clase Action que extienda PrincastPDFReportAction (abstracta)...........................256 14.4.5. Resultado final ..................................................................................................................259

15. Seguridad en aplicaciones con openFWPA ....................................................................................261 15.1. Seguridad .................................................................................................................................261

15.1.1. Autentificación básica.......................................................................................................262 15.1.2. Autentificación basada en formulario ...............................................................................262 15.1.3. Autentificación basada en el Filtro de Seguridad de openFWPA.....................................262

15.1.3.1. Integración con seguridad Web J2EE ........................................................................264 15.1.3.2. Configuración.............................................................................................................265

15.1.3.2.1. Parámetros básicos..............................................................................................265 15.1.3.2.2. Configuración JAAS...........................................................................................268 15.1.3.2.3. Reglas de Seguridad............................................................................................272

15.1.3.3. Paso de Credenciales..................................................................................................277 15.1.3.4. Diseño de páginas de login ........................................................................................280 15.1.3.5. Excepciones durante el proceso de autenticación ......................................................284 15.1.3.6. Niveles de Seguridad .................................................................................................284

16. Pruebas de rendimiento...................................................................................................................284 16.1. Tipos de pruebas ......................................................................................................................286

16.1.1. Pruebas de carga................................................................................................................286 16.1.2. Prueba de estrés.................................................................................................................286 16.1.3. Prueba de estabilidad (soak testing)..................................................................................286 16.1.4. Pruebas de picos (spike testing) ........................................................................................286

Page 7: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 7 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

16.2. Herramientas ............................................................................................................................286 16.3. Pruebas de rendimiento en openFWPA ...................................................................................287

17. Anexo: Consola de gestión de Tomcat 7 ........................................................................................288 17.1. Mensajes...................................................................................................................................290 17.2. Gestor .......................................................................................................................................290 17.3. Aplicaciones.............................................................................................................................291 17.4. Desplegar .................................................................................................................................293

17.4.1. Despliegue utilizando un directorio o un fichero WAR del propio servidor Tomcat.......293 17.4.1.1. Despliegue mediante el directorio o la URL del fichero WAR .................................293 17.4.1.2. Despliegue mediante el directorio o la URL en el directorio base de Tomcat ..........294 17.4.1.3. Despliegue mediante URL de archivo de configuración XML .................................295

17.4.2. Desplegar a través de un archive WAR externo ...............................................................295 17.5. Diagnósticos.............................................................................................................................295 17.6. Información del servidor..........................................................................................................296

Page 8: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 8 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

1. Control del documento

1.1. Información general

Título Manual de Instalación en Windows

Creado por: Jorge Méndez Rodríguez

A revisar por: Consultores Senior: Juan José Parada Vales e Ignacio Álvarez Valdeón

A aprobar por: Jefe de Proyecto: Joaquín Fernández Juárez

1.2. Histórico de revisiones

Versión Fecha Autor Observaciones

1.0 30/12/2011 Jorge Méndez Rodríguez

1.3. Estado del documento

Versión Estado Fecha

1.0 Definitivo 30/12/2011

Page 9: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 9 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

2. Introducción

El objetivo de este documento es detallar los diferentes componentes existentes en openFWPA y la configuración de los mismos a la hora de realizar una aplicación J2EE utilizando el Framework. En los diferentes apartados se muestran ejemplos, de utilización y configuración de los diferentes componentes, extraídos de la aplicación de ejemplo (sampleapp) que se distribuye con el Framework.

1 Aplicación de ejemplo - sampleapp

3. Desarrollo de aplicaciones

Antes de comenzar el desarrollo de una aplicación Web con openFWPA, es importante tener en cuenta las directrices y recomendaciones que se indican en este apartado.

Page 10: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 10 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

3.1. Estructura de directorios

Las aplicaciones definirán una estructura de directorios siguiendo la plantilla:

• build, target: Contendrá los .class generados para el proyecto. • src: Este directorio contendrá varios subdirectorios:

o db: Contendrá los scripts de creación de la base de datos o la propia base de datos. En caso de darse soporte a más de una base de datos o más de una versión, ha de crearse un directorio para cada una de las BD.

o config: Contendrá los ficheros necesarios para la creación del fichero EAR necesario para desplegar la aplicación en el contenedor J2EE (como por ejemplo application. xml), así como los ficheros con la información necesaria para la configuración de recursos que necesitará la aplicación (por ejemplo DataSources. En este caso podría incluirse un fichero data-sources.xml con la información a añadir al fichero data-sources.xml del contenedor J2EE para la definición de los mismos).

o main: � java: Contendrá los ficheros de código fuente Java y de recursos de la

aplicación, y el fichero build.xml con las taras de Ant. � jasperreports: Contendrá los fuentes de los informes generados con el Ireports. � resources: Contendrá los ficheros de properties con los parámetros de

configuración de la aplicación. • beans: Contendrá los xml donde están registrados las beans de Spring. • resources: Contendrá el fichero de properties con los mensajes

internacionalizados. • sqlMaps: Contendrá los xml asociados a los sql-maps de Ibatis.

� Webapp: • pages: Contendrá el resto de ficheros de la aplicación: páginas HTML,

JSP, imágenes, hojas de estilo CSS, etc. • WEB-INF: Contendrá los ficheros de configuración XML (web.xml,

strutsconfig.xml, validation.xml, etc.), DTDs y TLDs. • lib: Contendrá las librerías que será necesario distribuir con la

aplicación, puesto que no estarán incluidas en el contenedor J2EE. o test: Contendrá el conjunto de pruebas unitarias.

• dist: Se trata de un directorio temporal empleado para la generación de los jars, ears,… necesarios para el proyecto.

3.2. Compilación y despliegue del sistema

Maven es una herramienta de control para el control de la construcción y ciclo de vida de los proyectos de software. Será una de las piedras angulares de nuestro sistema, y lo utilizaremos entre otras cosas para realizar el compilado, generar los jar, los war, los ear, dependencias de otros jar,…

Page 11: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 11 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Los ficheros de configuración de Maven están escritos en XML y tienen por nombre pom.xml. Cada uno de ellos contiene los datos de configuración de nuestro proyecto como por ejemplo las dependencias con otros jar. En el directorio raíz de openFWPA existe un fichero pom.xml, que realiza la carga del resto de subproyectos (a través de sus correspondientes pom.xml) que tenemos disponibles en este Framework. <modules> <module> xml-generico </module> <module> fwpa-core </module> <module> fwpa-security </module> <module> fwpa-web-resources </module> <module> sampleapp </module> <module> blankapp </module> <module> proxies </module> <module> fwpa-doc </module> </modules> A continuación vamos a comentar las principales tareas que tendremos disponibles en Maven (como se verá en el manual de instalación, para agilizar el proceso de desarrollo se recomienda utilizar el plugin m2e para integrar maven con Eclipse):

• compile. Creará los .class y los dejará en el directorio target • test. Ejecuta los test unitarios disponibles en el proyecto, y muestra su resultado. • packaged. Creará el jar, war, ear, …, del proyecto, según la configuración que tenga el fichero

pom.xml del proyecto. • install. Añadirá el .jar del proyecto al repositorio local de Maven. • deploy. Útil si tenemos un repositorio de Maven en red. Hace las mismas tareas que install, y

después añade el .jar al repositorio en red. • javadoc:javadoc. Genera la documentación del proyecto • clean. Limpia el proyecto, eliminando los .class generados previamente por ejemplo a través

del comando “compile”.

3.3. Pruebas unitarias

Es muy recomendable la implementación de pruebas unitarias, al menos para todos los componentes críticos de la aplicación. Es también recomendable, en aplicaciones Web, implementar pruebas

Page 12: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 12 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

unitarias para todos los objetos de acceso a datos (DAO). Para facilitar esta tarea se puede utilizar la librería JUnit y DBUnit, suministrada en openFWPA.

4. Sistema de Logging (log4j)

Para la gestión de las sentencias de log, en openFWPA se utiliza la librería: Log4j (http://logging.apache.org/log4j/). Log4j tiene tres componentes principales:

• Loggers • Appenders • Layouts.

Estos tres tipos de componentes trabajan juntos para permitir a los desarrolladores escribir mensajes de log de acuerdo a un tipo de mensaje y prioridad, y para controlar en tiempo de ejecución la forma en que estos mensajes se formatean y donde se escriben.

Page 13: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 13 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

2 http://logging.apache.org/

4.1. Loggers

Son entidades con nombre. Sus nombres son sensibles al contexto y siguen una regla de nombrado jerárquica. Por ejemplo, el logger de nombre “com.foo” es padre del logger de nombre “com.foo.Bar”. El logger root reside en la cima de la jerarquía de loggers. Siempre existe y no puede ser recuperado por nombre. Para recuperarlo se ha de invocar a método estático Logger.getRootLogger(). Es posible asignar un nivel a un logger. Los niveles disponibles por orden de menor a mayor son:

• DEBUG. para mostrar mensajes de depuración.

Page 14: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 14 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• INFO. para mostrar información sobre lo que está haciendo la aplicación. • WARN. para mostrar mensajes de alerta sobre eventos de los que se desea mantener constancia,

pero que no afectan al correcto funcionamiento del problema. • ERROR. para mostrar mensajes de error que afectan a la aplicación, pero que lo permiten

seguir funcionando (por ejemplo, algún error en un parámetro de configuración). • FATAL. para mostrar mensajes críticos del sistema, generalmente después del mensaje la

aplicación finalizará. Si a un logger no se le asigna un nivel, lo hereda de su antecesor más cercano que tenga asignado uno. Para asegurarse que todos los loggers tienen un nivel, el logger raíz siempre tiene asignado un nivel. Las escrituras se realizan invocando a alguno de los métodos de impresión del logger: debug, info, warn, error, fatal y log. El método de impresión define el nivel de la escritura. Una escritura se dice que está habilitada si su nivel es mayor o igual que el nivel de su logger. De otra forma se dice que la escritura esta deshabilitada. El orden de los niveles es: DEBUG < INFO < WARN < ERROR < FATAL.

4.2. Appenders

Log4j permite que los mensajes se impriman en múltiples destinos, a cada uno de los cuales se le denomina Appender. Algunos de los Appenders disponibles son:

• ConsoleAppender. Escribe los mensajes de log en la consola. • FileAppender. Escribe los mensajes de log en un fichero. • RollingFileAppender. Escribe los mensajes de log a un fichero al que se le pueden definir

políticas de rotación para que no crezca indefinidamente. • DailyRollingFileAppender. Escribe los mensajes de log en un fichero a que se le puede definir

políticas de rotación basadas en la fecha. • SocketAppender. Escribe los mensajes de log hacia un servidor remoto de log. • SMTPAppender. Envía un correo electrónico con los mensajes de log, generalmente se utiliza

para los niveles ERROR y FATAL. • JDBCAppender. Escribe los mensajes de error a una base de datos. • SyslogAppender. Escribe los mensajes de error hacia el daemon syslog de los sistemas

operativos Unix. • NTEventLogAppender. Escribe los mensajes de log en los log del sistema de Windows NT. • JMSAppenders. Serializa los eventos y los transmite como mensaje JMS de tipo

ObjectMessage.

Page 15: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 15 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para más información sobre las opciones de configuración de los Appenders, consultar la documentación de Log4j.

4.3. Layouts

El Layout es el responsable de formatear los mensajes de log de acuerdo a las definiciones del desarrollador. Los tipos de Layouts disponibles son:

• SimpleLayout. Prioridad del mensaje seguida por “-“, y después el mensaje de log. • PatternLayout. Especifica el formato de salida de acuerdo a unos patrones de conversión

similares a los de la función “printf” del lenguaje C (para más información consultar la documentación).

• HTMLLayout. Especifica que la salida será una tabla HTML. • XMLLayout. Especifica que la salida será un fichero XML que cumple con el log4j.dtd. • TTCCLayout. Consiste en la fecha, thread, categoría y NDC, cualquiera de estos cuatro campos

puede ser deshabilitado y habilitado individualmente.

4.4. Configuración

En la siguiente imagen, “Estados del Sistema de Logging” se puede ver el ciclo de vida de la configuración del Sistema de Log de una aplicación que utiliza openFWPA.

Arranque

No Log

Runtime

Inicio Fin

3 Estados de Sistemas de Loggins

Page 16: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 16 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Los estados por los que puede pasar son los que siguen:

1. No Log. En este estado no hay configuración alguna cargada. Si se lanza alguna sentencia de log, aparecerá un WARNING en la salida estándar del servidor (openFWPA está configurado por defecto para utilizar Tomcat). Este estado no debería producirse pero se puede dar en caso de que se inicialicen componentes antes que el Framework (listeners, ejbs, etc.).

2. Arranque. Se carga la configuración de arranque del openFWPA. Esta configuración se definirá en el fichero log4j.properties ubicado en el classpath de la aplicación. En este fichero se puede definir una configuración de log, únicamente activa durante el proceso de arranque de la aplicación.

4 Path del fichero log4j.properties en openFWPA

A continuación se muestra el contenido por defecto del fichero “log4j.properties” en openFWPA.

log4j.rootCategory=info, Console, HTML log4j.category.org.springframework = debug

Page 17: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 17 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

log4j.category.es.princast.framework = debug log4j.appender.Console=org.apache.log4j.ConsoleAppe nder log4j.appender.Console.layout=org.apache.log4j.Patt ernLayout log4j.appender.Console.layout.ConversionPattern=%d{ ISO8601} %p %c[%t] - %m%n log4j.appender.HTML=org.apache.log4j.DailyRollingFi leAppender log4j.appender.HTML.File=appblank-startup-log.html log4j.appender.HTML.layout=es.princast.framework.co re.logging.layouts.PrincastHTMLLayout

3. Runtime. En este estado se supone activa la configuración de log de la aplicación. Esta configuración se define en el fichero xml indicado en el parámetro de configuración LOGGING_XMLCONF, o en el fichero de properties, cuyo path se indica en el parámetro de configuración, LOGGING_PROPERTIES. En openFWPA el parámetro LOGGING_XMLCONF se encuentra definido en el fichero “global.properties” que podemos encontrar en “WEB-INF/global.properties”, tal y como se indica en la siguiente imagen:

Page 18: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 18 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

5 Path del fichero global.properties en openFWPA

A continuación se muestra el contenido por defecto del fichero “global.properties” en openFWPA. HIT.COUNTER=es.princast.framework.core.management.m counters.historic.HistoricalCounter ACTION_MGMT=es.princast.framework.web.action.monito ring.PrincastActionMgmtInterfaceImpl LOGGING_XMLCONF=WEB-INF/log4j.xml http.PORT=8082 https.PORT=8447 https/cert.PORT=8447

Page 19: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 19 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

ITEM.SEPARATOR = / JMX.SERVER.ADAPTOR = es.princast.framework.core.management.adapters.OC4J MBeanServerAdapter

4.4.1. Ejemplo de configuración

El sistema de logging se configura a través de, por ejemplo, el fichero WEB-INF/log4j.xml (path que se especifica bajo la constante de configuración: LOGGING_XMLCONF, mostrada en el apartado anterior).

6 Path del fichero WEB-INF/log4j.xml

Page 20: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 20 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Puede verse un ejemplo de utilización en la aplicación en blanco (AppBlank) y en la de ejemplo (SampleApp). <?xml version ="1.0" encoding ="UTF-8" ?> <! DOCTYPE log4j:configuration SYSTEM "dtd/log4j.dtd" > <log4j:configuration xmlns:log4j ='http://jakarta.apache.org/log4j/' > <appender name="STDOUT" class ="org.apache.log4j.ConsoleAppender" > < layout class ="org.apache.log4j.PatternLayout" >

<param name="ConversionPattern" value ="Carrito: %d %-5p [%t] %c{2} (%F:%L) - %m%n" />

</layout> </appender> <aprender name="PERFORMANCE" class ="org.apache.log4j.DailyRollingFileAppender" > < param name="File" value ="carrito-performance.html" /> <layout class ="es.princast.framework.core.logging.layouts.Princas tHTMLLayout" > </ layout > </appender> <appender name="HTML" class ="org.apache.log4j.DailyRollingFileAppender" > < param name="File" value ="carrito-log.html" /> <layout class ="es.princast.framework.core.logging.layouts.Princas tHTMLLayout" > </layout> </appender> <appender name="AUDIT" class ="org.apache.log4j.DailyRollingFileAppender" > < param name="File" value ="carrito-audit.html" /> <layout class ="es.princast.framework.core.logging.layouts.Princas tHTMLLayout" > </ layout > </appender> <category name="es.princast.framework" > < priority value ="DEBUG" /> <appender-ref ref ="HTML" /> </category>

Page 21: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 21 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<category name="debug" > < priority value ="DEBUG" /> <appender-ref ref ="HTML" /> </category> <category name="PISTA_AUDITORIA" > < priority value ="INFO" /> <appender-ref ref ="AUDIT" /> </category> <category name="PISTA_RENDIMIENTO" > < priority value ="INFO" /> <appender-ref ref ="PERFORMANCE" /> </category> <root > < priority value ="INFO" /> <appender-ref ref ="STDOUT" /> </ root > </log4j:configuration> En este fichero se definen varios Appenders (o destinos donde el logger va a escribir). La salida estándar, un fichero HTML (que cambiará todos los días) y otro Appender de nombre Audit similar al anterior. Para cada uno de ellos se define también el layout o plantilla que se utilizará para escribir la salida. También se definen categorías, donde se especifica para cada logger el nivel que tendrá y los Appenders que utilizará. A continuación se muestra la salida de un Appender que escribe en un fichero HTML.

Page 22: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 22 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

7 Ejemplo de salida de un Appender en formato HTML

Para más información sobre la configuración del logger consultar la documentación del mismo en la dirección http://logging.apache.org/log4j/docs/manual.html.

Page 23: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 23 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

4.5. Componentes del openFWPA para Logging

4.5.1. LoggingManager

En openFWPA el controlador centralizado del sistema de Logging es la clase LogginManager, definido como un bean de Spring en el fichero “princast-init-script.xml”, como veremos a lo largo de este apartado. En el núcleo (core) del openFWPA se define la clase LoggingManager, cuyo objeto es ser un controlador centralizado para todo el Sistema de Logging. Esta clase permite:

• Cargar configuraciones Log4J desde ficheros (xml o de properties). • Obtener los loggers estándar del framework: Pista de Auditoría y Pista de Rendimiento.

El LoggerManager se puede gestionar desde la consola JMX.

Page 24: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 24 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8 Estados Path del fichero WEB_INF/princast-init-script.xml

Como ya comentamos, la clase LogginManager se define como un bean de Spring en el fichero “WEB_INF/princast-init-script.xml”, tal y como podemos ver a continuación: <!--Gestor de logging --> <bean id ="loggingManager" class ="es.princast.framework.core.logging.LoggingManager"

Page 25: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 25 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

factory-method ="getLogging" lazy-init ="false" singleton ="true" > </bean> Todo los beans definidos en el fichero “princast—init-script.xml” se cargan con el arranque de openFWPA.

4.5.2. PrincastHTMLLayout

Además de los layouts incluidos en Log4J (Ver “Layouts”), las aplicaciones también pueden utilizar PrincastHTMLLayout. Este objeto es igual que el HTMLLayout estándar, con la diferencia de que muestra la fecha y hora en que se escribe la sentencia de log.

4.5.3. Pistas de auditoría

Las aplicaciones han de registrar todas las operaciones de usuario que realicen en la denominada pista de auditoria. Para cada entrada aparecerá el usuario y la dirección IP desde la que se realizó la operación (registro NDC), más una descripción de la operación realizada. La salida es configurable, pudiendo ser de distintos formatos y en distintos soportes. Por defecto, se vuelca en un fichero en formato HTML. Cada día se mueve el contenido de este log a un fichero con la extensión .YYYY-MM-DD. El siguiente ejemplo se ha sacado de la aplicación de ejemplo, y muestra la ejecución de dos operaciones marcadas como auditables:

9 Ejemplo de operaciones auditadas

Un ejemplo de código que escribe información en la pista de auditoria sería el siguiente: LoggingManager.getLogging().getAuditingTrack().info ("[" + NDC.peek() + "] Añadiendo producto al carrito"); Se hace uso de la clase LoggingManager de openFWPA, la cual se obtiene mediante el método estático getLogging(). El método getAuditingTrack() del LoggingManager devolverá la pista de auditoria, en la cual se escribirá como si se tratase de cualquier otro logger. Es necesario incluir la información sobre el usuario y la IP desde la que está accediendo, información disponible mediante el método peek de la clase NDC de Log4j.

Page 26: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 26 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La pista de auditoria es un logger (Log4J) sobre el que se escribe la traza de accesos. Este logger se configura, de igual forma que los loggers de aplicación, utilizando el fichero log4j.xml. <appender name="AUDIT" class="org.apache.log4j.Dail yRollingFileAppender"> <param name="File" value="example-audit.html" /> <layout class="es.princast.framework.core.logging.layou ts.PrincastHTMLLayout"> </layout> </appender> <category name="PISTA_AUDITORIA"> <priority value ="INFO" /> <appender-ref ref="AUDIT" /> </category> El nombre del logger de auditoría se puede configurar en el fichero de inicialización de openFWPA: “princast-init-script.xml”, como se indica en el ejemplo. <bean id="loggingManager" class="es.princast.framework.core.logging.LoggingMa nager" factory-method="getLogging" lazy-init="false" singl eton="true"> <property name="auditingTrack"> <value>MY_AUDIT_TRACK</value>

</property> </bean> El nombre por defecto del logger de auditoría es: “PISTA_AUDITORIA”.

4.5.4. Pistas de rendimiento

La Pista de Rendimiento es un logger, muy similar a la Pista de Auditoría, que permite escribir las mediciones de rendimiento que se realicen en la aplicación. La configuración de la Pista de Rendimiento, se realizará en el fichero log4j.xml. <appender name="PERFORMANCE" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="example-audit.html" / > <layout class="es.princast.framework.core.logging.layou ts.PrincastHTMLLayout"> </layout> </appender>

Page 27: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 27 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<category name="PISTA_RENDIMIENTO"> <priority value ="INFO" /> <appender-ref ref="AUDIT" /> </category> El nombre del logger de rendimiento se puede configurar en la definición del LoggingManager en el fichero de arranque princast-init-script.xml. <bean id="loggingManager" class="es.princast.framework.core.logging.LoggingMa nager" factory-method="getLogging" lazy-init="false" singl eton="true"> <property name="performanceTrack"> <value>MY_PERFORMANCE_TRACK</value> </property> </bean> El nombre por defecto del logger de la Pista de Rendimiento es: “PISTA_RENDIMIENTO”. Para obtener los loggers estándar del Framework:

• Pista de Auditoría � getAuditingTrack() • Pista de Rendimiento � getPerformanceTrack()

5. Spring

Spring Framework es una plataforma que nos proporciona una infraestructura que actúa de soporte para desarrollar aplicaciones Java. Spring maneja toda la infraestructura y así te puedes centrar en tu aplicación. Diciéndolo más coloquialmente, Spring es el “pegamento” que une todos los componentes de la aplicación, maneja su ciclo de vida y la interacción entre ellos. Aunque es más habitual utilizar Spring en entornos Web, también se podría utilizar para cualquier otro tipo de aplicación que tengamos que desarrollar. Más información sobre Spring en http://www.springsource.org/.

Page 28: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 28 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

10 http://www.springsource.org/

5.1. Spring en openFWPA

Spring se encarga de gestionar las dependencias, instanciar los objectos e inyectarlos por reflexión. En resumen, se declaran en un fichero XML los componentes de tu aplicación y sus dependencias. Spring procesa este fichero XML, crea los componentes y sus relaciones entre ellos. En openFWPA se hace un uso intensivo de la inversión de control para implementar la arquitectura de referencia. En las aplicaciones realizadas con openFWPA se hace uso de Spring Framework, que ofrece la implementación del patrón AbstractFactory basado en ficheros XML.

Page 29: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 29 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Esto permite, eliminar los elementos de unión en las aplicaciones, como las factorías, y singletons. Además, permite tener la arquitectura modularizada en "piezas", que por estar definidas en un fichero XML, son intercambiables. Lo que deriva, en un sistema débilmente acoplado, más tolerable a cambios y modificaciones. Para manejar la Arquitectura de referencia con Spring, openFWPA se hace uso de una serie de ficheros XML, donde se definen los beans que forman parte de la arquitectura del sistema. Estos ficheros están ubicados en “src/java/beans” y sigue la estructura de directorios, propuesta para la arquitectura.

Page 30: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 30 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

11 Path del directorio bean en openFWPA

Los ficheros siguen la sintaxis de definición de beans de Spring, al igual que el fichero de inicialización de openFWPA (princast-init-script.xml). Para hacer uso de la inversión de control, es necesario seguir una serie de pasos. Como ejemplo, se va a ver cómo se construye una clase Action dependiente de una clase Delegate desde cero. El proceso de

Page 31: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 31 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

inyectar la dependencia se ha denominado "enlazado", tomándolo como traducción libre del término "wiring", utilizado en el manual de referencia de Spring. La primera tarea que hay que hacer, es implementar el Action. Como se tiene una dependencia, con un Delegate, se introduce un campo o propiedad (privado o protegido), en la clase Action. Además, se define un setter para ese campo, de esta forma se puede inyectar esa dependencia. A la hora de usar el objeto Delegate se utiliza normalmente, aunque parezca que al usarlo apunta a un valor nulo, el motor de inversión de control se encarga de inicializarlo. public class GetListaProductoAction extends Princas tListAction {

// inyeccion de dependencia (/beans/web/action-bean s.xml) protected CarritoDelegate carritoDelegate;

public void setCarritoDelegate(CarritoDelegate carr itoDelegate) {

this.carritoDelegate = carritoDelegate; }

protected Object getContentList(ActionMapping mappi ng, ActionForm form, HttpServletRequest request) {

//Llamamos al delegate para obtener la lista d e productos. return carritoDelegate.getListaProducto();

} } Una vez programada la clase, se debe registrar en el fichero de beans correspondiente, en este caso, como se trata de un Action, se registra en el fichero actions-beans.xml. Para ello se le da un identificador mediante el atributo id. Un nombre de clase con el atributo class, y mediante el atributo singleton, se especifica si se quiere que la clase sea un singleton o no (si no se especifica ese atributo, por defecto, será un singleton). <bean id="viewlistaproducto" class="es.princast.sampleapp.web.action.GetListaPro ductoAction" singleton="false"> <property name="carritoDelegate"> <ref bean="carritoDelegate" /> </property> </bean>

Page 32: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 32 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para inyectar la dependencia se realiza mediante el elemento property, donde se establece un atributo name, que coincide con el nombre asociado al setter, que se ha definido en la clase que se implementó anteriormente. En el contenido del elemento property, se hace referencia mediante ref al identificador (id) de otro bean. Este bean puede estar definido, en ese mismo fichero o en cualquiera de la estructura comentada anteriormente. En este caso, la definición es de un Delegate, por lo que estará definido en el fichero delegate-beans.xml. <bean id="carritoDelegate" class="es.princast.sampleapp.web.delegate.CarritoDe legate"> <property name="carritoManager"> <ref bean="carritoManager"/> </property> <property name="formasPagoManager"> <ref bean="formasPagoManager"/> </property> <property name="agenciasManager"> <ref bean="agenciasManager"/> </property> </bean>

5.2. Estableciendo el datasource

La inversión de control, comienza desde la primera dependencia que se tiene. En este caso el datasource, para ello se define en el fichero “datasource-beans.xml”, un bean que representa un datasource JNDI, a continuación se muestra un ejemplo de definición del mismo (aplicación de ejemplo “sampleapp”): <!-- Configuración del DataSource mediante fichero de properties--> <bean id="propertyConfigurerJDBC" class="org.springframework.beans.factory.config.Pro pertyPlaceholderConfigurer">

<property name="location"> <value>classpath:jdbc.properties</value>

</property> </bean>

Page 33: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 33 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<!-- JNDI Datasource --> <jee:jndi-lookup id="dataSource" jndi-name="${jndi. datasource}"/> En el caso de la aplicación de ejemplo, se ha definido en el fichero “src/main/resources/jdbc.properties” el valor de “jndi.datasource”, tal y como se muestra ver a continuación. Datasource JNDI jndi.datasource=java:comp/env/jdbc/carritoDS Para realizar las pruebas unitarias, es necesario disponer de un datasource para realizar los test. En la aplicación de ejemplo, se suministra un test sobre una clase DAO, que utiliza un datasource para test, disponible en “src/test/resources/beans/datasourceTest-beans.xml”.

12 Path del fichero datasourceTest-beans.xml

Page 34: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 34 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Un ejemplo de definición de datasource de test, es el siguiente: <!-- DataSource para Test Unitarios --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverMa nagerDataSource">

<property name="driverClassName"> <value>${jdbc.driverClassName}</value>

</property>

<property name="url"> <value>${jdbc.url}</value>

</property>

<property name="username"> <value>${jdbc.username}</value>

</property>

<property name="password"> <value>${jdbc.password}</value>

</property> </bean> <!-- Se necesita el transactionManager para el test --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSour ceTransactionManager">

<property name="dataSource"> <ref bean="dataSource"/>

</property> </bean> En el caso de la aplicación de ejemplo, se han definido en el fichero “src/test/resources/jdbc-

test.properties” el valor de “jdbc.driverClassName”, “jdbc.url”, “jdbc.username”, “jdbc.password”, tal y como se muestra ver a continuación. jdbc.driverClassName=org.gjt.mm.mysql.Driver jdbc.url=jdbc:mysql://localhost/carrito jdbc.username=xxxx jdbc.password=xxxx

Page 35: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 35 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

13 Path del fichero jdbc-test.properties

5.3. Enlazando con los DAOs

Una vez definido el datasource, se definen los DAOs, para ello se utiliza el fichero “dao-beans.xml”. A continuación se muestra un ejemplo de definición: <!-- iBatis DAOs --> <bean id="carritoDAO" class="es.princast.sampleapp.business.dao.IBATISCar ritoDAO"> <property name="sqlMapClient"><ref bean="sqlM apClient"/></property> <property name="displayTagSize">

<ref bean="displayTagPageSize"/> </property>

Page 36: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 36 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</bean> <bean id="formaPagoDAO" class="es.princast.sampleapp.business.dao.IBATISFor maPagoDAO"> <property name="sqlMapClient">

<ref bean="sqlMapClient"/> </property>

</bean> <!-- JDBC DAOs --> <bean id="carritoDAO" class="es.princast.sampleapp.business.dao.MySQLCarr itoDAO"> <property name="dataSource">

<ref bean="dataSource"/> </property>

</bean> <bean id="formaPagoDAO" class="es.princast.sampleapp.business.dao.MySQLForm aPagoDAO"> <property name="dataSource">

<ref bean="dataSource"/> </property>

</bean>

5.4. Enlazando con los Manager

Para registrar los Managers como beans de Spring y enlazarlos los DAOs, se utiliza en el fichero “manager-beans.xml”. Hay que tener en cuenta, si el manager que se está definiendo, está sujeto a transacciones. A continuación, se muestra la declaración de un Manager que no está sujeto a transacciones y que no tiene ninguna dependencia con DAOs: <!-- Este no esta sujeto a transacciones luego decl aracion normal --> <bean id="agenciasManager" class="es.princast.sampleapp.business.manager.Agenc iasManager">

Page 37: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 37 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</bean> <bean id="logoutConfigurable" class="es.princast.sampleapp.business.manager.Logou tConfigurable"> </bean> <bean id="displayTagPageSize" class="es.princast.sampleapp.business.manager.Displ ayTagSizeConfigurable"> </bean> En el caso de estar sujeto a transacciones, la definición del bean es un poco más complicada, ya debe heredar de una plantilla para transacciones. Esto se realiza mediante el atributo parent, donde se le especifica el nombre de la plantilla, que estará definida en el fichero transaction-beans.xml. La definición propiamente dicha de la clase Manager, se realiza dentro de la propiedad target, y se le inyecta las dependencias normalmente. A continuación, se muestra la definición de un Manager sujeto a manejo de transacciones. <bean id="carritoManager" parent="transactionTempla te"> <property name="target"> <bean

class="es.princast.sampleapp.business.manager. CarritoManager"> <property name="carritoDAO">

<ref bean="carritoDAO"/> </property>

</bean> </property>

</bean> <bean id="formasPagoManager" class="es.princast.sampleapp.business.manager.Forma sPagoManager">

<property name="formaPagoDAO"> <ref bean="formaPagoDAO"/> </property>

</bean> La dependencia se establece por medio de la definición de un setter, para cada campo dependiente en la clase que representa al Manager. public class CarritoManager { ...

Page 38: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 38 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

protected CarritoDAO carritoDAO; public void setCarritoDAO(CarritoDAO carritoDAO) { this.carritoDAO = carritoDAO; } ... }

5.4.1. Gestión de transacciones

Desde el fichero “transaction-bean.xml” se controla la gestión de transacciones. Esta gestión se realiza de forma declarativa, por lo que los Managers que hereden de estas plantillas de transacciones, no tendrán que implementar código para la gestión de transacciones, ni conexiones. Antes de la definición de la plantilla se establece un transactionManager sobre el datasource a utilizar. Un ejemplo de definición es el siguiente: <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSour ceTransactionManager"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> Una vez declarado el “transactionManager”, se define una plantilla para el manejo de transacciones. De esta plantilla se debe de heredar, en la definición de beans, los Manager que estén sujetos a transacciones. Se podrían definir varias plantillas, en función de las necesidades. Un ejemplo de plantilla para la gestión de transacciones es el siguiente: <bean id="transactionTemplate" abstract="true" class="org.springframework.transaction.interceptor. TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="transactionManager" /> </property> <property name="transactionAttributes">

Page 39: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 39 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<props> <!--Los métodos que comiencen por get en los Mana ger serán readOnly--> <prop key="get*">PROPAGATION_REQUIRED,readOnly</ prop> <prop key="find*">PROPAGATION_REQUIRED,readOnly< /prop> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> Como se observa en el ejemplo de plantilla, se dispone de una property de nombre transactionAttributes, que define las propiedades de la transacción. Las transacciones se definen a nivel de método de un Manager, por lo que, cada ejecución de un método de un Manager establecería una transacción. Además se pueden establecer patrones, de forma que definiendo el patrón 'get*', las propiedades establecidas para ese patrón, afectará a todos los métodos del Manager que comiencen por 'get'. De esta manera definiendo las propiedades, 'PROPAGATION_REQUIRED,readOnly' se tendrá una transacción por método, y además estará optimizada para sólo lectura. El comportamiento por defecto, para la política de rollback, define que si se produce una excepción de tipo Runtime durante la ejecución del método, se hará un rollback. Algunas de las propiedades que se pueden establecer son:

• PROPAGATION_LEVEL: Nivel de propagación. Por defecto se establece el nivel de propagación a PROPAGATION_REQUIRED, esto significa que creará una nueva transacción, sólo si se necesita.

• ISOLATION_LEVEL: Nivel de aislamiento. Por defecto trendrá el valor ISOLATION_DEFAULT.

• readOnly: Optimización de sólo lectura. Se optimiza la transacción para las operaciones de sólo lectura.

• Lista de Excepciones: Establece la política de rollback o commit, al margen del comportamiento por defecto. Por ejemplo, si se le añade la cadena '-MiExcepcion', se hará rollback en caso de que dispare la excepción de nombre 'MiExcepcion', aunque el tipo de excepción no sea Runtime. Si se añade la cadena '+OtraExcepcion', se hará commit aunque la excepción sea Runtime.

Para más información sobre las propiedades disponibles consultar el manual de referencia de Spring.

Page 40: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 40 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

5.5. Enlazando con los Delegate

Para enlazar las definiciones de Managers, con las clases Delegate, se hace de manera similar a los enlazados visto anteriormente, en este caso se realiza en el fichero delagate-beans.xml. Un ejemplo de enlazado es el siguiente: <bean id="carritoDelegate" class="es.princast.sampleapp.web.delegate.CarritoDe legate"> <property name="carritoManager"> <ref bean="carritoManager"/>

</property>

<property name="formasPagoManager"> <ref bean="cachedFormasPagoManager"/>

</property> <property name="agenciasManager"> <ref bean="agenciasManager"/>

</property> </bean> Se recuerda que la clase CarritoDelegate debe disponer de un setter para cada dependencia.

5.6. Enlazando con los Actions

Una vez enlazados los Delegates, se deben enlazar las Actions. Para ello se definen los beans en el fichero action-beans.xml. Un ejemplo, de definición de beans para las Actions es el siguiente: <bean id="carrito" class="es.princast.sampleapp.web .action.CarritoActions" scope="prototype"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property>

</bean> <!-- propiedad singleton="false" --> <bean id="viewlistaproductopdf" singleton="false"

Page 41: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 41 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

class="es.princast.sampleapp.web.action.report.Prod uctosPDFTableReportAction"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property>

</bean> En el caso de las Actions, si queremos que se cree una instancia por cada petición de struts, estableceremos el atributo singleton="false”. Una vez definidos los beans para las Actions deben ser referenciados desde el fichero “WEB-

INF/struts-config.xml”, la referencia se hará mediante el atributo type. Buscará primero por id de bean definido en el fichero action-beans.xml, y si no encuentra ningún bean definido, tomará el nombre como el de una clase. Un ejemplo de Actions en struts-config.xml: <!—- Se referencia al id de un bean definido en el fichero action-beans.xml --> <action path="/viewdetalleproducto" name="detallePr oductoForm" input="/index.jsp" type="viewdetalleproducto" scope ="request" validate="false"> <forward name="success" path="carrito.detall eprod" /> </action> <!—- se tiene en cuenta el nombre de la clase --> <action path="/viewcarrito" validate="false" parameter="carrito.viewcarrito" type="es.princast.framework.web.action.PrincastForw ardAction" scope="request"> </action> Se observa que el atributo type tiene el valor type="viewdetalleproducto" que coincide con el id del bean definido en action-beans.xml.

6. Capa de acceso a datos

Un componente básico del modelo es la capa de acceso a datos (generalmente, a bases de datos relacionales). No está permitido el acceso a datos desde cualquier componente de la aplicación que no

Page 42: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 42 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

pertenezca a esta capa (páginas JSP, Actions, etc.). La herramienta clave para la implementación de esta capa es el patrón de diseño DAO (Data Access Object). El principal objetivo es:

• Abstraer al resto de la aplicación de los detalles de implementación del acceso a sistemas de persistencia.

• Homogeneizar el acceso a datos desde las capas superiores.

14 Ejemplo de capa de acceso a datos

6.1. Alternativas para implementar la capa de acceso a datos

Para realizar el acceso a datos se utilizará el patrón DAO (Data Access Object), openFWPA contempla dos alternativas:

• Clases proporcionadas por el FW-PA o Interface PrincastDAO o PrincastDAOHelper o PropertiesTableDAO o LookupPropertyBean

• iBATIS (http://www.mybatis.org/)

OpenFWPA está configurado por defecto para trabajar con iBATIS, y por tanto en este manual de configuración nos centraremos en esta alternativa.

Page 43: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 43 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

15 http://www.mybatis.org/

6.2. ¿Qué es iBATIS?

iBATIS es un framework (método de trabajo) de código abierto basado en capas desarrollado por Apache Software Foundation, que se ocupa de la capa de Persistencia (se sitúa entre la lógica de Negocio y la capa de la Base de Datos). iBATIS asocia objetos de modelo (JavaBeans) con sentencias SQL o procedimientos almacenados mediante ficheros descriptores XML, simplificando la utilización de bases de datos. El 21 de Mayo de 2010 el equipo de desarrollo decidió continuar el proyecto en Google Code bajo la nueva denominación MyBatis.

Page 44: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 44 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

6.2.1. iBATIS en openFWPA

Para comenzar se comentarán brevemente los componentes que se deben tener en cuenta al desarrollar una aplicación J2EE con openFWPA utilizando iBATIS.

• Value Object (nombreVO). Los objetos de datos han de implementar PrincastValueObject. Como “BasePrincastVO” implementa esta interface, los nuevos objetos de datos deben extender de la clase “BasePrincastVO” incluida en el core de openFWPA.

16 Diagrama de Value Objects

Page 45: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 45 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra un ejemplo de un VO para la clase “FormaPagoVO”. public class FormaPagoVO extends BasePrincastVO { .... private int id; .... public int getId() { return id; } public void setId(int id) { this.id = id; } .... }

Page 46: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 46 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

17 Path de la clase FormaPagoVO

• DAO (Data Access Object). Para realizar el acceso a datos se utilizará el patrón DAO (Data Access Object). En primer lugar se debe definir una interface, con todos los métodos que se

Page 47: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 47 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

deben implementar. Después se debe crear la implementación, que debe extender de “PrincastSqlClientDAOSupport” para acceder a Base de Datos.

18 Path de la capa de acceso a datos en openFWPA

Page 48: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 48 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra un ejemplo de una interface. public interface FormaPagoDAO { List getFormaPago(); } Y de una implementación de dicha interface public class IBATISFormaPagoDAO extends PrincastSqlClientDAOSupport implements Fo rmaPagoDAO { // constantes para los identificadores de las consultas private static String LISTA_FORMAPAGO = "lista FormaPago"; public List getFormaPago() { return getPrincastSqlMapClientTemplate().query ForList(LISTA_FORMAPAGO, null); } } A continuación se mapean en el fichero “sqlMapConfig.xml” los campos de la tabla correspondiente de la base de datos con los atributos equivalentes del VO, y se especifican las consultas a realizar en la capa de acceso a datos. En cada una de ellas se indica que parámetros recibe y en que Mapping se va a obtener el resultado (se le puede indicar que el resultado me lo devuelva en una tabla Hash).

Page 49: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 49 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

19 Path del fichero sqlMapConfig.xml

Es recomendable incluir en el “sqlMapConfig.xml” ficheros auxiliares para mantener organizada la información, tal y como podemos ver en el siguiente ejemplo.

Page 50: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 50 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Contenido del fichero “sqlMapConfig.xml”. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD S QL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd "> <sqlMapConfig> <settings /> <sqlMap resource="sqlMaps/FormaPagoDAO.xml" /> </sqlMapConfig> Como podemos ver en el código anterior, se utiliza un fichero auxiliar para el mapeo de los atributos y la especificación de las consultas “FormaPagoDAO”. A continuación se muestra el contenido del fichero “FormaPagoDAO.xml”. <sqlMap namespace="FormaPagoDAO"> <resultMap class="es.princast.sampleapp.business .vo.FormaPagoVO" id="formaPagoMap"> <result property="id" column="id"/> <result property="description" column="descri pcion"/> </resultMap> <select id="listaFormaPago" resultMap="formaPago Map"> SELECT * FROM formapago </select> </sqlMap> El siguiente paso será las clases de los daos como beans de Spring en el fichero “dao-beans.xml”, tal y como se vio en el apartado “3.2.3. Enlazando con los DAOs”. Por ser un DAO que utiliza Ibatis a la hora de registrarlo como un bean de Spring hay que pasarle la propiedad sqlMapClient que es una referencia al bean. <bean id="formaPagoDAO" class="es.princast.sampleapp.business.dao.IBATISFor maPagoDAO"> <property name="sqlMapClient">

<ref bean="sqlMapClient"/>

Page 51: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 51 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</property> </bean> Que se definió previamente en el mismo fichero, tal y como se muestra a continuación: <!-- SqlMap configuración para iBATIS Database Laye r --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientF actoryBean"> <property name="dataSource"><ref bean="data Source"/></property> <property name="configLocation"> <value>classpath:/sqlMaps/sqlMapConfig. xml</value> </property> </bean>

6.3. Pool de conexiones

Cuando trabajamos con java contra una base de datos, es habitual que se realice una conexión a base de datos por cada operación que se quiera realizar. Esto podría ser adecuado para una aplicación muy básica, pero en proyectos complejos es mejor utilizar otras formas para evitar por ejemplo los siguientes problemas: : Abrir una conexión, realizar cualquier operación con la base de datos y cerrar la conexión puede ser lento. La apertura de las conexiones puede tardar más que la operación que queremos realizar. Es mejor, por tanto, abrir una o más conexiones y mantenerlas abiertas. Mantener una única conexión abierta compartida puede traernos problemas de concurrencia de hilos. Si varios hilos intentan hacer una operación con la conexión sin sincronizarse entre ellos, puede haber conflictos. El esquema conexión-operación-desconexión visto anteriormente es válido, pero podría ser más eficiente si no fuera necesario abrir las conexiones constantemente. En vez de esta orientación hay otra alternativa: crear un pool de conexiones, es decir, mantener un conjunto limitado de conexiones que se reutilizan constantemente para dar servicio a las diferentes operaciones. Para realizar una operación contra la base de datos se solicita una conexión al conjunto de conexiones disponibles, y cuando no la va a usar la devuelve al pool. De esta forma nos ahorramos el consumo de tiempo de conexión y desconexión. En openFWPA, el pool de conexiones está definido en el fichero “datasource-beans.xml”.

Page 52: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 52 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

20 Path del fichero datasource-beans.xml

A continuación podemos ver el contenido de este fichero. <!-- Configuración del DataSource mediante fichero de properties--> <bean id="propertyConfigurerJDBC" class="org.springframework.beans.factory.config.Pro pertyPlaceholderConfigurer"> <property name="location"> <value>classpath:jdbc.properties</value> </property> </bean>

Page 53: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 53 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<!-- JNDI Datasource –> <jee:jndi-lookup id="dataSource" jndi-name="${jndi. datasource}"/> El primer bean representa la conexión por JDBC y el segundo representa la conexión por JNDI (Java Naming and Directory Interface). Puedes obtener más información sobre JNDI en la siguiente página de Oracle: http://www.oracle.com/technetwork/java/jndi/index.html. La variable ${jndi.datasource} está definida en el fichero “jdbc.properties”, y su contenido es: #Datasource JNDI jndi.datasource=java:comp/env/jdbc/carritoDS

21 Path del fichero jdbc.properties

Page 54: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 54 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Como hemos visto a través de los ejemplos anteriores, por defecto openFWPA está configurado para que la conexión se realice utilizando JNDI.

6.3.1. Datasource en Apache Tomcat

Como hemos visto en el documento de instalación del entorno, openFWPA está configurado por defecto para trabajar con Apache Tomcat. Por ese motivo, tenemos que definir en el fichero “context.xml” ubicado en el directorio META-INF los datos de acceso a la base de datos.

22 Path del fichero context.xml

A continuación se muestra el contenido del fichero “context.xml”. Context docBase="carrito" path="/carrito" reloadabl e="true" source="org.eclipse.jst.j2ee.server:carrito">

Page 55: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 55 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<!-- <ResourceLink name="jdbc/carritoDS" global="jdbc/carritoDS" type="javax.sql.DataSource"/> --> <!-- mysql --> <Resource name="jdbc/carritoDS" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle ="30" maxWait="10000" username="root" password="root" driverClassName="co m.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/carrito?autoReconn ect=true"/> <!-- postgresql <Resource name="jdbc/carritoDS" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle ="30" maxWait="10000" username="carrito" password="carrito" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/carrito"/> --> </Context> Como podemos comprobar, a pesar de que openFWPA trabaja por defecto con MySQL, en este fichero se incluyen entre comentarios la configuración necesaria para trabajar con PostgreSQL

6.4. Pruebas unitarias

Es muy recomendable la implementación de pruebas unitarias, al menos para todos los componentes críticos de la aplicación. Es también recomendable, en aplicaciones Web, implementar pruebas unitarias para todos los objetos de acceso a datos (DAO). Toda aplicación J2EE desarrollada utilizando openFWPA debería tener presente, en todo momento, la realización de pruebas unitarias de todos sus componentes relevantes. De esta forma se tiene una batería de pruebas que pueden ejecutarse en cualquier momento como pruebas de regresión. Debiera disponerse de un proceso en el servidor que se encargue de lanzar tales pruebas un número determinado de veces y genere un informe con los resultados de la ejecución de las pruebas. Todo esto se ha tenido en cuenta a la hora de desarrollar opnFWPA y se proporciona una infraestructura basada en JUnit (http://www.junit.org/) que se puede utilizar a tal efecto.

Page 56: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 56 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

23 http://junit.org/

6.4.1. Convenciones a seguir

A la hora de implementar las diferentes pruebas unitarias se recomienda que las clases sigan el convenio de nombrado masivamente seguido que establece que éstas deben llamarse <nombre_de_la_clase>Test.java. En cuanto a la signatura de los métodos que implementen los diferentes casos de pruebas, se suele emplear: public void test<nombre_caso_prueba> () {}; JUnit reconoce como casos de prueba todos aquellos métodos que sigan esta convención de nombrado.

Page 57: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 57 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

6.4.2. Pruebas unitarias de objetos que acceden a bases de datos

Para una aplicación Web es muy recomendable realizar pruebas unitarias para todos los objetos de acceso a bases de datos (DAOs), de esta forma se garantiza que el back-end de la aplicación está correctamente implementado y se agiliza en muy buena medida el desarrollo de la capa Web. Las pruebas unitarias de acceso a bases de datos, se realizan siempre fuera del contendor. Esto es lógico ya que en un buen diseño nunca un componente de acceso a base de datos tendrá dependencias respecto al contendor donde se ejecuta. Para realizar pruebas de clases que deben acceder a una base de datos, se utilizará la clase de test PrincastDatabaseTestCase o la clase AbstractTransactionalDataSourceSpringContextTests (la clase anterior hereda de ésta). Las pruebas unitarias de objetos que acceden a bases de datos, están basadas en el Framework Spring. Spring puede simular el acceso a la base de datos utilizando transacciones serializables que son canceladas una vez termina la prueba. Por este motivo, es importante que las tablas involucradas en las pruebas que se implementan, dispongan de soporte para transacciones (por ejemplo, las tablas de tipo MyISAM, por defecto en MySQL, no soportan transacciones, sin embargo las tablas de Oracle o las tablas InnoDB de MySQL sí que las soportan). El hecho de que este tipo de pruebas unitarias esté basado en Spring supone que:

• Es necesario declarar los DataSources que se van a utilizar en un fichero de definición de beans de Spring.

• No es necesario controlar las transacciones que se realicen durante el test. • La clase de prueba es, a su vez, un bean de Spring. La clase de pruebas realizará autowiring por

tipo para todas sus propiedades setter. Es decir, para todos los setters que tenga la clase de pruebas busca, en los ficheros de definición de beans, un bean que encaje en el tipo de la propiedad y se lo asigna.

Atención

Es muy importante tener en cuenta que el autowiring de beans con la clase de test se realiza por tipo. Si más de un bean encaja en el tipo de la propiedad puede producirse un error. El DataSource a utilizar también se asigna a la clase de test utilizando autowiring, por lo tanto, únicamente se puede declarar un DataSource en los ficheros de definición de beans.

Page 58: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 58 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para implementar tests extendiendo de la clase PrincastDatabaseTestCase o de la clase AbstractTransactionalDataSourceSpringContextTests, se seguirán todas las normas y convenciones definidas para implementar casos de prueba estándar (ver apartado “3.6.1. Convenciones a seguir”). Si extendemos de “PrincastDatabaseTestCase” se debe implementar el método:

• getDataSourceFile(), que devuelve el path donde se encuentra el fichero de definción de beans en el que se declara el DataSource a utilizar. Por ejemplo:

protected String getDataSourceFile() {

return "classpath*:/es/princast/framework/facilitie s/dao/datasource-beans.xml"; } La clase base “PrincastDatabaseTestCase” proporciona las siguientes utilidades:

• logger. Como todos los tests, se dispone de un atributo, de nombre logger, que permite acceder al log de la clase de prueba.

• getDataSource(). Este método permite obtener la fuente de datos (DataSource) que conecta con

la base de datos. Este origen de datos se puede asignar, posteriormente, a los objetos que se vayan a probar.

• jdbcTemplate. La clase base para pruebas en base de datos dispone de un atributo, de la clase

org.springframework.jdbc.core.JdbcTemplate, que permite ejecutar, directamente consultas contra la base de datos. Para más información sobre cómo usar esta clase, consúltese el manual de referencia del Framework Spring.

• onSetUpInTransaction(). Extendiendo este método, se pueden realizar todo tipo de

actualizaciones (inserciones, borrados, etc.) que sean necesarios para la posterior ejecución de la prueba. Todas las actualizaciones que se realicen estarán disponibles, únicamente durante la ejecución del test. No quedará rastro de estas operaciones en la base de datos.

Este método sustituye al fichero DataSet XML de dbUnit. Si se utiliza este método, y se quiere utilizar también dbUnit, se debe hacer una llamada a super.onSetUpInTransaction().

• onSetUpBeforeTransaction(). Este método es análogo al anterior con al diferencia de que las

actualizaciones realizadas en este método sí que son persistentes en la base de datos.

Page 59: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 59 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Si por el contrario extendemos de “AbstractTransactionalDataSourceSpringContextTests” se debe implementar el método:

• getConfigLocations(), que devuelve un array con el path donde se encuentra el fichero de definción de beans en el que se declara el DataSource a utilizar, y el path de los beans que se han definido en la aplicación. Por ejemplo:

public String[] getConfigLocations() { return new String[] { "classpath*:/beans/business/ manager-beans.xml", "classpath*:/beans/business/transaction-beans.x ml", "classpath*:/beans/business/dao-beans.xml", "classpath*:/beans/business/search-beans.xml", "classpath*:/beans/princast-init-scriptTest.xml ", "classpath*:/beans/datasourceTest-beans.xml" }; } La clase base “AbstractTransactionalDataSourceSpringContextTests” proporciona las siguientes utilidades:

• logger. Como todos los tests, se dispone de un atributo, de nombre logger, que permite acceder al log de la clase de prueba.

• jdbcTemplate. La clase base para pruebas en base de datos dispone de un atributo, de la clase

org.springframework.jdbc.core.JdbcTemplate, que permite ejecutar, directamente consultas contra la base de datos. Para más información sobre cómo usar esta clase, consúltese el manual de referencia del Framework Spring.

• jdbcTemplate.getDataSource(). En este caso tendremos que utilizar el método a través del

atributo comentado justo en el punto anterior. Al igual que sucede con la clase “PrincastDatabaseTestCase”, este método permite obtener la fuente de datos (DataSource) que conecta con la base de datos. Este origen de datos se puede asignar, posteriormente, a los objetos que se vayan a probar.

• onSetUpInTransaction(). Extendiendo este método, se pueden realizar todo tipo de

actualizaciones (inserciones, borrados, etc.) que sean necesarios para la posterior ejecución de la prueba. Todas las actualizaciones que se realicen estarán disponibles, únicamente durante la ejecución del test. No quedará rastro de estas operaciones en la base de datos.

Page 60: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 60 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• onSetUpBeforeTransaction(). Este método es análogo al anterior con lA diferencia de que las actualizaciones realizadas en este método sí que son persistentes en la base de datos.

6.4.2.1. Pruebas unitarias de DAOs

Por habitual, un caso especial de las pruebas unitarias que acceden a bases de datos, es el de las pruebas unitarias de DAOs. Los objetos DAO a probar se deben declarar en un fichero de definición de beans de Spring. La ubicación de este ficho se proporcionará extendiendo el método “getDaoFile()” en el caso de la extender de la clase “PrincastDatabaseTestCase”, y el método “getConfigLocations()” si extendemos de la clase “AbstractTransactionalDataSourceSpringContextTests”, como ya comentamos anteriormente. Para obtener instancias de los DAOs a probar, la clase de pruebas debe definir un método setter para cada uno de ellos. La clase base utilizada se encargará de asignar a estas propiedades los DAOs, declarados en el fichero de definción de beans, cuyo tipo sea compatible (autowiring por tipo). Es importante tener en consideración que, si más de un bean es compatible con el tipo de una propiedad del test, se puede producir un error. A continuación vamos a ver una clase de prueba de ejemplo para un DAO, utilizando la clase base “AbstractTransactionalDataSourceSpringContextTests”. public class CarritoDAOTest extends AbstractTransactionalDataSourceSpringContex tTests { // DAO a probar protected CarritoDAO carritoDAO; // la dependencia de inyecta automáticamente por e l tipo de clase public void setCarritoDAO(CarritoDAO carritoDAO) { this.carritoDAO = carritoDAO; } public String[] getConfigLocations() { return new String[] { "classpath*:/beans/business/m anager-beans.xml", "classpath*:/beans/business/t ransaction-beans.xml", "classpath*:/beans/business/d ao-beans.xml", "classpath*:/beans/business/s earch-beans.xml", "classpath*:/beans/princast-i nit-scriptTest.xml",

Page 61: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 61 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

"classpath*:/beans/datasource Test-beans.xml" }; } // tareas que se realizan antes de los test public void onSetUpInTransaction() { // se borra lo que hay y se insertan los datos de test // se recuerda que la transaccion se hara rollbac k por lo que no // afecta al contenido, siempre y cuando la tabla sea de tipo InnoDB jdbcTemplate.execute("delete from producto"); jdbcTemplate.execute("insert into producto values(1,'test1','test1','test1',1)"); jdbcTemplate.execute("insert into producto values(2,'test2','test2','test2',2)"); jdbcTemplate.execute("insert into producto values(3,'test3','test3','test3',2)"); } public void testGetProductos() { jdbcTemplate.getDataSource(); logger.info("Iniciado testGetProductos"); assertNotNull(carritoDAO); List list = carritoDAO.getListaProducto(); assertTrue(list.size() == 3); logger.info("Lista de productos 3 "); logger.info("Finalizado testGetProductos"); } public void testGetDetalle() { logger.info("Iniciado testGetDetalle"); assertNotNull(carritoDAO); ProductoVO producto = carritoDAO.getDetalleProduc to("1"); assertTrue(producto.getName().equals("test1")); logger.info("Finalizado testGetDetalle"); } }

Page 62: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 62 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Con solamente implementar el método setCarritoDAO(), al ejecutar el test se asignará automáticamente cualquier bean de la clase CarritoDAO. En el método getConfigLocations() se debe definir la ubicación del fichero de definición de beans donde se declaran los DAOs. En este caso, nos afectan directamente “/beans/business/dao-beans.xml” y “/beans/business/manager-beans.xml”, porque en el “dao-beans.xml” se hace referencia a un bean definido en el “manager-beans.xml” (displayTagPageSize). El contenido del fichero “dao-beans.xml” es el siguiente: <!-- SqlMap configuración para iBATIS Database Laye r --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientF actoryBean"> <property name="dataSource"><ref bean="dataSource" /></property> <property name="configLocation"> <value>classpath:/sqlMaps/sqlMapConfig.xml</value > </property> </bean> <!-- iBatis DAOs --> <bean id="carritoDAO" class="es.princast.sampleapp.business.dao.IBATISCar ritoDAO"> <property name="sqlMapClient"><ref bean="sqlMapCli ent"/></property> <property name="displayTagSize"> <ref bean="displayTagPageSize"/> </property> </bean> <bean id="formaPagoDAO" class="es.princast.sampleapp.business.dao.IBATISFor maPagoDAO"> <property name="sqlMapClient"><ref bean="sqlMapCli ent"/></property> </bean> En el método getConfigLocations() también se define la ubicación del fichero de declaración de beans donde se especifica el DataSource a utilizar. En este ejemplo, el fichero se llama “/beans/datasourceTest-beans.xml”, y su contenido es el que sigue: <beans>

Page 63: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 63 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<!-- DataSource para Test --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverMa nagerDataSource"> <property name="driverClassName"> <value>${jdbc.driverClassName}</value> </property> <property name="url"><value>${jdbc.url}</value></p roperty> <property name="username"><value>${jdbc.username}< /value></property> <property name="password"><value>${jdbc.password}< /value></property> </bean> <!-- Se necesita el transactionManager para el test --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSour ceTransactionManager"> <property name="dataSource"><ref bean="dataSource" /></property> </bean> </beans> Todas las operaciones realizadas sobre la base de datos en este método serán únicamente visibles a lo largo del test (si el tipo de nuestra tabla, suponiendo que trabajemos con MySQL, es innoDB). Finalmente, se puede realizar el test normalmente utilizando los beans declarados en los ficheros correspondientes.

Atención

El test de ejemplo que se ha comentado se puede encontrar, junto con un test para la capa “Manager”, dentro de la aplicación de ejemplo (sampleapp) incluida en openFWPA.

6.4.2.2. Más información sobre la implementación de pruebas unitarias

Dado que los diferentes tipos de pruebas unitarias que se han presentado con anterioridad están basados en proyectos de terceros, la mejor forma de conseguir información detallada de los mismos es acudiendo a los sitios Web de estos. Por ello, a continuación se presentan los enlaces a las guías de desarrollo de cada uno de los proyectos:

Page 64: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 64 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• Proyecto JUnit [ http://junit.sourceforge.net/] • Proyecto StrutsTestCase [http://jtestcase.sourceforge.net] • Proyecto DbUnit [http://dbunit.sourceforge.net/howto.html]

7. Capa de negocio

Es importante disponer de un buen diseño técnico antes de programar la lógica de negocio. En esta área intervienen dos tipos de objetos:

• Business Delegates • Business Managers

Los objetos “Delegate” se encargarán de crear y gestionar los objetos de lógica de negocio y proporcionarán un interfaz, para la aplicación Web, de los métodos de negocio. Los objetos "Manager", se encargarán de implementar la propia lógica de negocio.

7.1. Business Managers

En esta capa se implementa toda la lógica de negocio, dando soporte a los procesos de negocio asociados, como por ejemplo hacer una transacción bancaria. Si requiere acceder a datos en una base de datos o en otro sistema, se apoya en la capa de acceso a datos comentada en el apartado anterior. Además oculta toda la complejidad a la capa superior que se verá en el siguiente apartado.

Page 65: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 65 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

24 Path del directorio Manager

Como ya vimos en el apartado “5.4. Enlazando con los Manager”, las clases asociadas a la capa de negocio “Manager” se registran como beans de Spring en el fichero manager-beans.xml.

Page 66: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 66 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

25 Path del fichero manager-beans.xml

7.1.1. Prueba unitaria sobre la capa Manager

En este apartado vamos a comentar ver la clase de prueba “CarritoManagerTest.java”, que utiliza la clase base “AbstractTransactionalDataSourceSpringContextTests”, y que se incluye dentro de la aplicación de ejemplo “sampleapp” de openFWPA.

Page 67: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 67 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

26 Path de la clase de prueba CaritoManagerTest.java

A continuación se muestra el código de la clase “CarritoManagerTest”: public class CarritoManagerTest extends AbstractTransactionalDataSourceSpringContextTests { private CarritoManager carritoManager; public CarritoManagerTest() { setAutowireMode(AUTOWIRE_BY_NAME); setDefaultRollback(false); } public void setCarritoManager(CarritoManager carri toManager) { this.carritoManager = carritoManager; }

Page 68: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 68 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

// fichero donde esta el datasource de test public String[] getConfigLocations() { return new String[] { "classpath*:/beans/business/manager-beans.xml", "classpath*:/beans/business/transaction-beans.x ml", "classpath*:/beans/business/dao-beans.xml", "classpath*:/beans/business/search-beans.xml", "classpath*:/beans/princast-init-scriptTest.xml ", "classpath*:/beans/datasourceTest-beans.xml" }; } public void testFindProductosPorNombre() { List todos = carritoManager.getListaProducto(); List productos = carritoManager.findProductosPorNombre("Producto") ; Assert.assertTrue(productos.size() > 0); } } Con solamente implementar el método setCarritoManager(), al ejecutar el test se asignará automáticamente cualquier bean de la clase CarritoManager. En el método getConfigLocations()se define la ubicación del fichero de declaración de beans donde se especifica el DataSource a utilizar “datasourceTest-beans.xml”, así como la ubicación de los ficheros de definición de beans donde se declaran los Managers. A continuación se muestra el contenido del fichero “datasourceTest-beans.xml”: <beans> <!-- DataSource para Test --> <bean id="dataSource"

class="org.springframework.jdbc.datasource.DriverMa nagerDataSource"> <property name="driverClassName">

Page 69: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 69 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<value>${jdbc.driverClassName}</value> </property> <property name="url"><value>${jdbc.url}</value></p roperty> <property name="username"><value>${jdbc.username}< /value></property> <property name="password"><value>${jdbc.password}< /value></property> </bean> <!-- Se necesita el transactionManager para el test --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSour ceTransactionManager"> <property name="dataSource"><ref bean="dataSource" /></property> </bean> </beans> Respecto a los ficheros que incluyen la definición de los beans donde se declaran los Managers, aunque el método “getConfigLocations” de la clase “CarritoManagerTest” haga referencia a varios ficheros, en este caso concreto nos afectan únicamente “manager-beans.xml” y “dao-beans.xml”, ya que como podremos ver en el siguiente ejemplo (contenido del fichero “manager-beans.xml”), los beans “carritoManager” y “formasPagoManager” hacen referencia a “carritoDAO” y “formasPagoDAO” respectivamente, definidos en el fichero “dao-beans.xml”. A continuación se muestra el contenido del fichero “manager-beans.xml” es el siguiente: <!-- Para que estén sujetos a transacciones tienen que tener parent="transactionTemplate" y la property "ta rget" apuntando a la clase de esta manera obtienen y cierran la con exión automáticamente --> <bean id="carritoManager" parent="transactionTempla te"> <property name="target"> <bean class="es.princast.sampleapp.business.manag er.CarritoManager"> <property name="carritoDAO"><ref bean="carritoDAO "/></property> </bean> </property> </bean>

Page 70: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 70 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<bean id="formasPagoManager" class="es.princast.sampleapp.business.manager.Forma sPagoManager"> <property name="formaPagoDAO"><ref bean="formaPago DAO"/></property> </bean> <!-- Este no esta sujeto a transacciones luego decl aración normal --> <bean id="agenciasManager" class="es.princast.sampleapp.business.manager.Agenc iasManager"> </bean> <bean id="logoutConfigurable" class="es.princast.sampleapp.business.manager.Logou tConfigurable"> </bean> <bean id="displayTagPageSize" class="es.princast.sampleapp.business.manager.Displ ayTagSizeConfigurable"> </bean> Por último, recordar que las clases “CarritoManager” y “FormasPagoManager” tiene definidos los setters “setCarritoDAO” y “setFormaPagoDAO” respectivamente, que utilizará Spring para inyectar los correspondientes beans, A continuación se muestra parte del contenido de la clase “CarritoManager”. public class CarritoManager { ... protected CarritoDAO carritoDAO; public void setCarritoDAO(CarritoDAO carritoDAO) { this.carritoDAO = carritoDAO; } ... }

Page 71: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 71 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

7.2. Business Delegate

Esta capa se encargarán de crear y gestionar los objetos de lógica de negocio, reducir el acoplamiento entre los clientes de la capa de presentación y los servicios de negocio, y proporcionarán un interfaz, para la aplicación Web, de los métodos de negocio. Además, esta capa oculta los detalles de la implementación de todos los servicios de negocio, como por ejemplo los detalles de una búsqueda.

27 Estructura de la capa Business Delegate

Utilizando esta estructura, se puede modificar la implementación del servicio sin que sea necesario modificar el resto de la aplicación. Un ejemplo de implementación puede verse en la aplicación de

Page 72: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 72 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

ejemplo (sampleapp). En ningún caso la lógica de negocio ha de tener dependencias con el protocolo http (como por ejemplo hacer uso de la sesión), ya que sus servicios han de poder reutilizarse desde cualquier otro entorno (como Web Services, JMS, etc.). Las únicas dependencias al protocolo concreto de acceso han de estar en las acciones (View Adapters y Actions).

28 Path del directorio Delegate

Como se comentó brevemente en el apartado “5.4. Enlazando con los Delegate”, las clases asociadas a la capa de negocio (Delegate) se registran como beans de Spring en el fichero delegate-beans.xml.

Page 73: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 73 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

29 Path del fichero manager-beans.xml

A continuación se mostrará el contenido del fichero “delegate-beans.xml”, donde podremos ver que el bean “carritoDelegate” está referenciando a tres beans de la capa de Manager. <!-- Declaracion de los delegates --> <bean id="carritoDelegate" class="es.princast.sampleapp.web.delegate.CarritoDe legate"> <property name="carritoManager"> <ref bean="carritoManager"/> </property> <property name="formasPagoManager">

Page 74: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 74 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<ref bean="cachedFormasPagoManager"/> </property> <property name="agenciasManager"> <ref bean="agenciasManager"/> </property> </bean> Tanto “carritoManager” como “agenciasManager” están definidos en el fichero “manager-

beans.xml”, mientras que “cachedFormasPagoManager” se encuentra en el fichero “cache-

beans.xml”, desde el que se hace referencia a “formasPagoManager” como podemos ver a continuación: ... <bean id="cachedFormasPagoManager" parent="abstractCarritoCacheProxyFactoryBean"> <property name="target" ref="formasPagoManager" /> </bean> ...

Page 75: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 75 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

30 Path del fichero cache-beans.xml

Para terminar con la capa Delegate, se muestra parte del contenido de la clase “CarritoDelegate”, donde podremos comprobar que se han definido los setters correspondientes para la inyección de las dependencias. public class CarritoDelegate { // Dependencias inyectadas /beans/web/delegates-be ans.xml private CarritoManager carritoManager; private FormasPagoManager formasPagoManager; private AgenciasManager agenciasManager;

Page 76: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 76 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

// set para la injeccion de dependencias public void setAgenciasManager(AgenciasManager age nciasManager) { this.agenciasManager = agenciasManager; } // set para la injeccion de dependencias public void setCarritoManager(CarritoManager carri toManager) { this.carritoManager = carritoManager; } // set para la injeccion de dependencias public void setFormasPagoManager(FormasPagoManager formasPagoManager)

{ this.formasPagoManager = formasPagoManager; } ... }

8. Controlador

OpenFWPA se basa en el Framework de Struts, un proyecto de la Apache Software Foundation orientado a la construcción de aplicaciones Web, que implementa la arquitectura Modelo 2 (MVC). El núcleo del Framework Struts es una capa de control flexible basada en tecnologías estándar como servlets, JavaBeans, ResourceBundles y XML, así como varios paquetes del proyecto Jakarta Commons. (http://jakarta.apache.org/commons). La figura siguiente muestra como es el ciclo petición-accion-jsp del Framework Struts:

Page 77: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 77 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

31 Ciclo petición-acción-jsp de Struts

Para obtener información más detallada sobre Struts consultar la página http://struts.apache.org/.

Page 78: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 78 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

32 http://struts.apache.org/

Para la implementación de aplicaciones Web, utilizando el openFWPA, es necesario definir correctamente el fichero web.xml, tal y como veremos a continuación.

8.1. web.xml

El fichero web.xml es el núcleo de las aplicaciones Web basadas en Struts, y por tanto también lo es de openFWPA.

Page 79: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 79 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

33 Path del fichero web.xml

Page 80: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 80 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Tal y como se ha hecho en los apartados anteriores, tomaremos como ejemplo el fichero “web.xml” de la aplicación de ejemplo (sampleapp) para comentar las distintas secciones que se incluyen en este fichero. El primer bloque que nos encontramos es “display-name”, que es un elemento opcional y se utiliza para especificar el nombre que tendrá la aplicación Web, y que en el caso de la aplicación de ejemplo es “carrito”. <display-name>carrito</display-name> El siguiente conjunto de elementos hacen referencia al arranque e inicialización de la aplicación. Se trata de la variable de contexto que indica la ubicación del fichero de arranque, que como ya vimos anteriormente, es el “princast-init-script.xml”. <context-param>

<param-name>INIT.SCRIPT.FILE</param-name> <param-value>/WEB-INF/princast-init-script.xml</par am-value>

</context-param> El siguiente bloque que se encuentra es el referente a la configuración de filtros, como podemos ver en el código mostrado a continuación. Esta sección (filter) define, además del nombre del filtro, la clase que actualizará como filtro (normalmente estas clases deben extender de “PrincastFilter”) y sus atributos de inicialización. <filter> <filter-name>SecurityFilter</filter-name> <filter-class> es.princast.framework.web.filter.security.corp.Pri ncastSecurityFilter

</filter-class> </filter> <filter> <filter-name>NavigationFilter</filter-name> <filter-class> es.princast.framework.web.filter.navigation.Navig ationFilter

</filter-class> </filter> <filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>

Page 81: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 81 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

org.tuckey.web.filters.urlrewrite.UrlRewriteFilte r </filter-class> <init-param>

<param-name>logLevel</param-name> <param-value>WARN</param-value>

</init-param> </filter> <filter>

<filter-name>loginFilter</filter-name> <filter-class>

es.princast.sampleapp.web.filter.LoginFilter </filter-class>

</filter> El siguiente bloque es “filter-mapping”, y se utilizará para mapear los filtros definidos anteriormente bien con un patrón de URL o con un Servlet. Es importante tener en cuenta que la sección “filter-

mapping” no puede ser definida antes que la sección “filter” dentro del fichero web.xml. Este bloque tiene tres propiedades que comentaremos brevemente a continuación.

• <filter-name>: Hace referencia al nombre (filter-name) del filtro definido en la sección anterior “filter” que se mapeará con un patrón de URL o con un Servlet.

• <url-pattern>: Describe el patrón utilizado para resolver la URL en que se mapeará el filtro.

Ejemplos de patrones son “/*” o “/action/*”.

• <servlet-name>: Hace referencia al nombre del Servet que, tras recibir una petición, provocará la ejecución del filtro. Este campo debe utilizarse en el caso de que no se haya introducido un patrón para la URL.

A continuación vemos el bloque “filter-mapping” incluido en el web.xml de la aplicación de ejemplo (sampleapp) de openFWPA. <filter-mapping>

<filter-name>SecurityFilter</filter-name> <url-pattern>/*</url-pattern>

</filter-mapping> <filter-mapping>

<filter-name>NavigationFilter</filter-name> <url-pattern>/action/*</url-pattern>

Page 82: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 82 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</filter-mapping> <filter-mapping>

<filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern>

</filter-mapping> <filter-mapping>

<filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern>

</filter-mapping> El bloque “listener” recibe notificaciones al producirse varios tipos de eventos, como por ejemplo al arrancar una aplicaciónción, o al crear/eliminar una sesión. Todos los “listener” se definen de la misma manera, ya que existe un único elemento llamado “<listener-class>”, donde se registra el nombre de la clase que responderá al evento (estas clases deben implementar la interfaz adecuada en función del tipo de evento al que quieran responder), tal y como podemos ver a continuación. <listener>

<listener-class> es.princast.framework.web.startup.PrincastStart upListener

</listener-class> </listener> El bloque “servlet” contiene la declaración de los Servlets específicos de la aplicación y sus parámetros de configuración. A continuación comentaremos brevemente los elementos más comunes que se pueden incluir en este bloque.

• <servlet-name>: Define el alias que tendrá el Servlet disponible en este bloque, y que se utilizará en otro bloque para referenciar a dicho Servlet.

• <servlet-class>: Define la clase del Servlet.

• <jsp-file>: Define la ruta relativa (respecto al directorio raíz) de la página JSP dentro de la

aplicación Web .Este campo debe utilizarse en el caso de que no se haya introducido la clase del Servlet (servlet-class).

Page 83: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 83 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• <init-param>: Elemento opcional que define los parámetros de inicialización del Servlet (pares clave-valor).

• <load-on-startup>: Elemento opcional que sirve para inicializar el Servlet al arrancar el

servidor. o En caso de existir, su contenido debe ser un número entero positivo que especificará el

orden en que el Servlet será cargado (un Servlet con este atributo a 1 se cargará antes que un Servlet con este atributo a 2).

o En caso de no existir, o tener un valor negativo, el servidor cargará el Servlet en el orden que considere oportuno.

A continuación vemos el bloque “servlet” incluido en el “web.xml” de la aplicación de ejemplo (sampleapp) de openFWPA. <servlet> <servlet-name>dwr-invoker</servlet-name>

<display-name>DWR Servlet</display-name> <description>Direct Web Remoter Servlet</descriptio n> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</serv let-class> <init-param>

<param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>logLevel</param-name> <param-value>DEBUG</param-value> </init-param> </servlet> <servlet>

<servlet-name>carrito</servlet-name> <servlet-class>

es.princast.framework.web.action.PrincastAction Servlet </servlet-class> <init-param>

<param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-va lue>

</init-param> <init-param>

<param-name>detail</param-name> <param-value>3</param-value>

</init-param> <init-param>

Page 84: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 84 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<param-name>validating</param-name> <param-value>true</param-value>

</init-param> <init-param>

<param-name>definitions-config</param-name> <param-value>/WEB-INF/tiles-defs.xml</param-value >

</init-param> <load-on-startup>1</load-on-startup>

</servlet> Al igual que sucedía con el bloque “filter”, los Servlets también deben ser mapeados. Para esto se utilizará el bloque “servlet-mapping”, aunque a diferencia del bloque “filter-mapping”, los Servlets únicamente se pueden mapear a través de un patrón de URL. <servlet-mapping> <servlet-name>carrito</servlet-name> <url-pattern>/action/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> El bloque “welcome-file-list” contiene una lista con las páginas de inicio de la aplicación, de forma que si se realiza una petición al directorio raíz de nuestra aplicación, el servidor revisa analiza esta sección para intentar mostrar la página de inicio configurada (por ejemplo podemos especificar dos páginas, “index.html” y “default.html”, de forma que primero se intenta mostrar la página “index.html” y en caso de no existir, se intenta mostrar la página “default.html”). <welcome-file-list>

<welcome-file>index.jsp</welcome-file> </welcome-file-list> El bloque “error-page” define el mapeo de los errores (a través de códigos de error <error-code> o de tipos de Excepción <exception-type>) producidos en la aplicación, con el recurso procesará este problema. Hay que tener en cuenta que no se pueden mostrar juntos en el mismo bloque “error-page” los elementos “error-code” y “exception-type” (debe aparecer únicamente uno de los dos). <error-page>

Page 85: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 85 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<error-code>404</error-code> <location>/pages/404Error.jsp</location>

</error-page> <error-page>

<error-code>500</error-code> <location>/pages/unknownError.jsp</location>

</error-page> <error-page>

<error-code>400</error-code> <location>/pages/400Error.jsp</location>

</error-page> <error-page>

<error-code>401</error-code> <location>/pages/unknownError.jsp</location>

</error-page> <error-page>

<error-code>403</error-code> <location>/pages/unknownError.jsp</location>

</error-page> <error-page>

<error-code>501</error-code> <location>/pages/unknownError.jsp</location> </error-page> <error-page> <error-code>502</error-code> <location>/pages/unknownError.jsp</location> </error-page> <error-page> <error-code>503</error-code> <location>/pages/unknownError.jsp</location> </error-page> El bloque “taglib” define las librerías de etiquetas JSP utilizadas en la aplicación, de forma que posteriormente en las páginas JSP se puede referencia una librería a través del elemento “taglib-uri” definido para una librería de etiquetas. <taglib>

Page 86: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 86 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<taglib-uri>/WEB-INF/tld/princast</taglib-uri> <taglib-location>/WEB-INF/tld/princast.tld</taglib- location>

</taglib> Para terminar con el análisis del fichero “web.xml” disponible en la aplicación de ejemplo de openFWPA (sampleapp), veremos el bloque “resource-ref”, que se utiliza para definir recursos externos que se utilizarán en la aplicación Web, como por ejemplo una conexión con una base de datos. <resource-ref>

<res-ref-name>jdbc/carritoDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Unshareable</res-sharing-scope>

</resource-ref> Si lo deseas, puedes obtener más información sobre el fichero web.xml en http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp/web_xml.html.

8.2. Declaración de las Actions

Las aplicaciones desarrolladas con openFWPA, están basadas en el Framework Spring. Para poder inyectar dependencias en las Actions de las aplicaciones, al igual que vimos con las capas anteriores, deben estar definidas como beans de Spring. En concreto, las definiciones de Actions se realizarán en el fichero “beans/web/action-beans.xml”, ubicado en el CLASSPATH, tal y como podemos ver en la siguiente imagen.

Page 87: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 87 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

34 Path del fichero action-beans.xml

A continuación vemos el contenido del fichero “action-beans.xml” perteneciente a la aplicación de ejemplo “sampleapp”. <bean id="logout" scope="prototype" class="es.princast.sampleapp.web.action.LogoutActio n"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> <property name="logoutConfigurable">

<ref bean="logoutConfigurable" /> </property> </bean>

Page 88: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 88 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<bean id="carrito" scope="prototype" class="es.princast.sampleapp.web.action.CarritoActi ons"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean> <bean id="viewdetalleproducto" scope="prototype" class="es.princast.sampleapp.web.action.GetDetalleP roductoAction"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean> <bean id="viewlistaproducto" class="es.princast.sampleapp.web.action.GetListaPro ductoAction" scope="prototype"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean> <bean id="viewperfil" scope="prototype" class="es.princast.sampleapp.web.action.GetPerfilAc tion" > </bean> <bean id="confirmar" scope="prototype" class="es.princast.sampleapp.web.action.ConfirmarAc tion" > <property name="formasPagoHelper">

<ref bean="formasPagoHelper" /> </property> </bean> <bean id="envio" scope="prototype" class="es.princast.sampleapp.web.action.SolicitudEn vioAction" > </bean> <bean id="confirmpedido" scope="prototype" class="es.princast.sampleapp.web.action.ConfirmPedi doAction" > <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean>

Page 89: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 89 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<bean id="viewlistaproductopdf" scope="prototype" class="es.princast.sampleapp.web.action.report.Prod uctosPDFReportAction" > <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean> <bean id="viewlistaproductoxml" scope="prototype" class="es.princast.sampleapp.web.action.xml.Product osRSSAction"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean> <bean id="busquedaProductos" scope="prototype" class="es.princast.sampleapp.web.action.BusquedaPro ductos"> <property name="carritoDelegate">

<ref bean="carritoDelegate" /> </property> </bean> <bean id="formasPagoHelper" class="es.princast.sampleapp.web.action.FormasPagoH elper"> <property name="delegateCarrito">

<ref bean="carritoDelegate" /> </property> </bean> Mientras que las Actions (clases) se declaran en el fichero “action-beans.xml”, todos los aspectos relativos a la navegación (forwards), mappings, formularios, etc. se han de declarar en el fichero “struts-config.xml” (se verá en el apartado “8.5. Mapeo en el fichero struts-config.xml”). De todas formas, en esta sección adelantamos que en la sección <action-mappings> del fichero “struts-config.xml”, se debe indicar el identificador (id) del bean que implementa la lógica de la Action, utilizando el atributo "type". Si el valor de este atributo es el identificador de un bean (de la clase Action), se tomará dicho bean para procesar las peticiones. Si el valor del atributo “type” es el nombre de una clase (una Action), se instanciará normalmente. A continuación vemos un ejemplo del mapeo en el fichero “struts-config.xml” de las Actions definidas más arriba como beans de Spring. <action-mappings>

Page 90: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 90 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

...

<action path="/login" type="login" scope="request" validate="false" input="/pages/login.jsp"> <forward name="success" path="/action/viewperfil" redirect="true" /> <forward name="failure" path="/action/login" redi rect="true" />

</action>

<action path="/logout" type="logout" scope="request "> <forward name="success" path="/action/login" redi rect="true" />

</action> ... </action-mappings>

Atención

Para poder realizar este tipo de mapeos es necesario utilizar como controlador en el fichero “struts-config.xml” (Controller) la clase PrincastRequestProcessor.

<controller processorClass="es.princast.framework.web.action.Pr incastRequestProcessor" />

8.3. Jerarquía de Actions

OpenFWPA se basa en el Framework de Struts, siendo el Servet controlador una especialización del “ActionServlet” del Framework de Struts.

Page 91: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 91 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

OpenFWPA se proporciona un conjunto de Actions de Struts. Estas Actions definen un nuevo ciclo de ejecución diferente del existente en las Actions típicas de Struts que se verá un poco más adelante. Las aplicaciones que utilicen openFWPA deben obligatoriamente, obligatoriamente extender las Actions del Framework A continuación se muestra la jerarquía de clases definidas en openFWPA para las Actions.

35 Jerarquía de Actions

Dentro de openFWPA, las “Actions” estarán disponibles en el directorio “action”, tal y como se muestra en la siguiente imagen.

Action PrincastActio

n

PrincastDispatchActio

PrincastExistAttributeAction

PrincastForwardAction

PrincastParameterAction

PrincastRemoveAttributeAction custom:

: PrincastCRUDActiocustom:

PrincastCRUDFormActio

custom:PrincastCustomDispatchActio

PrincastPDFReportActio PrincastListAction

Page 92: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 92 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

36 Path de las Actions

8.3.1. Clase PrincastAction

La clase base de la jerarquía es PrincastAction. Es una clase abstracta que implementa una máquina de estados de la que podrán hacer uso el resto de Actions. Define métodos que deben ser sobrescritos por las Actions de la aplicación. Estos métodos sobrescritos serán invocados por el Framework para dar respuesta a una solicitud de un cliente, y en un orden preestablecido.

Page 93: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 93 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Este orden se presenta como un esquema de la máquina de estados:

37 Maquinaria de Estados de PrincastAction

Cada uno de los métodos que aparecen en la figura anterior tiene un cometido en particular. Este cometido es el siguiente:

Llamada la método execute()

PreProcess

Hay errores?

findFailure

Hay mensajes?

findAle rt

executeLogic excepcion

catchException

postProcess

Hay errores?

findFailure

Hay mensajes?

findSuccess

findAlert

[Sí]

[No]

[Sí]

[Si]

[No]

[No]

[Si]

[No]

Page 94: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 94 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• preProcess (). Se emplea para comprobar las precondiciones que debe cumplir la

PrincastAction. En caso de que no se cumpla alguna precondición se debe dejar un registro de ello mediante la creación de un error o un mensaje, dependiendo de la gravedad del mismo. Al dejar constancia de la incidencia se redireccionará el flujo de ejecución hacia una página de error o a una de alerta, invocándose findFailure() y findAlert(), respectivamente.

• executeActionLogic (). Implementa la lógica de negocio de la PrincastAction. Éste será el

método sobrescrito de forma obligatoria por todas las acciones que hereden de PrincastAction.

• catchException(). Se encarga del tratamiento de cualquier excepción que se pueda lanzar durante la ejecución de la lógica de negocio de la PrincastAction. Si no se quiere que la excepción sea lanzada de nuevo debe notificarse su tratamiento mediante la llamada al método unsetException(). De esta forma se entenderá que todo el tratamiento necesario ya ha sido llevado a cabo y la excepción no será elevada.

• postProcess(). Se emplea para comprobar las poscondiciones que debe cumplir la

PrincastAction. En caso de que no se cumpla alguna poscondición se debe dejar constancia de ello mediante la creación de un error o un mensaje. Al dejar constancia de la incidencia se redireccionará el flujo de ejecución hacia una página de error o a una de alerta, invocándose findFailure() y findAlert(), respectivamente.

• findFailure(). Redirecciona a una página de error. Por defecto, la redirección se hace a lo que

se indique en el atributo input de la Action. En caso de que este atributo no sea definido se intentará hacer la redirección a un forward llamado “failure”.

• findAlert(). Redirecciona a una página de alerta en la que se muestra un mensaje informativo.

Por defecto la redirección se hace a un forward llamado “warning”.

• findSuccess(). Redirecciona a la página de éxito, es decir, a aquella a la que se debería ir si la ejecución de la acción no tiene ningún error. Por defecto se redirecciona a un forward llamado “success”.

8.3.1.1. Creando un error en una PrincastAction

OpenFWPA posee soporte integrado a la gestión de errores para usuario. Por error se entiende cualquier situación anómala en la aplicación, sea por un fallo del sistema o por datos incorrectos suministrados por el usuario. Los errores que no son tratados por las aplicaciones se muestran al usuario final.

Page 95: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 95 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra un ejemplo de creación de un error: protected void preProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

java.util.List error = new java.util.ArrayList(); error.add(“error.general”); saveErrors(error);

}; Para crear un error, se debe crear una instancia de java.util.List a la que se le añadirán hasta cinco elementos. El primero de estos elementos es la clave asociada al mensaje de error en el fichero de recursos. En caso de que el mensaje de error sea una simple cadena de caracteres (como ocurre en el ejemplo) bastará con un solo parámetro. En caso de que el mensaje lleve parámetros de la forma {0},{1},{2},{3}, un posible mensaje sería: error.general=Ha ocurrido un error de tipo {0} a la s {1} horas en {2} con usuario {3} En este caso, la creación del error sería como sigue: java.util.List error = new java.util.ArrayList(); error.add(“error.general”); error.add(“GRAVE”); // Parámetro {0} error.add(“15:30”); // Parámetro {1} error.add(“Gestión de usuarios”); // Parámetro {2} error.add(“Administrador”) // Parámetro {3} saveErrors(error); El usuario de la aplicación vería el siguiente mensaje: Ha ocurrido un error de tipo GRAVE a las 15:30 hora s en Gestión de usuarios con usuario Administrador

8.3.1.2. Creando un mensaje de advertencia en una PrincastAction

La forma de crear un mensaje de advertencia es similar al de la creación de un mensaje de error, con la salvedad de que en lugar de llamar al método saveErrors(List) se ha de invocar el método saveMessages(List).

Page 96: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 96 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.3.1.3. Modificando una redirección

En el curso de tratamiento de una petición, puede ser necesario redirigir la petición a otro Servet. PrincastAction proporciona una implementación por defecto para las redirecciones que pueden tener lugar durante la ejecución de una petición a una acción. Los métodos que se encargan de estas redirecciones son:

• findSuccess(). Redirecciona a un forward etiquetado “success”.

• findFailure(). Redirecciona a lo que se indique en el atributo input del elemento <action> correspondiente o a un forward etiquetado “failure” en caso de que no se defina el atributo input.

• findAlert(). Redirecciona a un forward etiquetado “warning”.

Todos ellos siguen la misma signatura: ActionForward find<redireccion> (ActionMapping mapp ing, ActionForm form, HttpServletRequest request, HttpServletResponse response); La forma de modificar la redirección de estos métodos es devolviendo una instancia diferente del ActionForward. Por ejemplo, imaginemos que cuando la ejecución de la PrincastAction tenga éxito, deseamos que se nos redireccione a un forward etiquetado como “ok”. En este caso, deberíamos sobrescribir el método findSuccess() como se muestra a continuación: ActionForward findSuccess(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

return mapping.findForward(“ok”); }; Como se puede apreciar en el ejemplo anterior, la cuestión es obtener del mapping (o crear indicando el path) un ActionForward a donde deseamos redireccionar la repuesta.

Page 97: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 97 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

ActionForward findSuccess(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { return new ActionForward("ok", "/action/test?metho d=ok", true); };

8.3.1.4. Almacenamiento interno de una Action

Las Actions de Struts no son thread-safe, por tanto, no es correcto utilizar atributos de instancia para compartir información entre los distintos métodos del ciclo de vida de una Action. En las ocasiones en que fuera indispensable utilizar un atributo de instancia, se recomienda utilizar el almacenamiento interno de la Action. Este almacén es un mapa de parámetros thread-local, cuyo ámbito se limita a los métodos del ciclo de vida de la Action (preProcess(), executeActionLogic(),

catchException() y postProcess()).

Page 98: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 98 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

38 Almacenamiento interno de las Actions

Para acceder y manipular este almacenamiento, la PrincastAction dispone de los siguientes métodos:

• deleteActionParameter( nombre ): Borra del almacén el parámetro especificado. • getActionParameter( nombre ): Obtiene del almacén el parámetro cuyo nombre se especifica.

• getActionParameters( nombre ): Obtiene un iterador con los nombres de todos los parámetros

del almacén.

• setActionParameter( nombre , valor ): Almacena un parámetro identificándolo con el nombre dado.

Page 99: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 99 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra un ejemplo de uso de este almacén: public class MyAction extends PrincastAction {

public MyAction(){ setActionParameter("param1", "value1");

}

protected void preProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { setActionParameter("param2", "value2");

}

protected void executeActionLogic(ActionMapping map ping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String param1 = (String) getActionParameter("para m1"); String param2 = (String) getActionParameter("para m2"); ...

} } En la Action del ejemplo anterior, MyAction se han sobrescrito dos métodos del ciclo de vida de la Action:

• preProcess() • executeActionLogic().

En el método preProcess(), se establece el valor de un parámetro “param2”, asignándole la cadena “value2”. Por otro lado, en el constructor, se establece un valor para el parámetro “param1”. En el método executeActionLogic(), se recuperan los valores de ambos parámetros. Recuérdese que únicamente los métodos del ciclo de vida de la ejecución de la Action tienen visibilidad del almacén. Por este motivo, en el método executeActionLogic(), la variable param2 tomará el valor “value2”, mientras que la variable param1 tendrá como valor “null”.

Page 100: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 100 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.3.1.5. Interrupción de la maquinaria de estados de la Action

En algunas ocasiones es necesario interrumpir el proceso de la maquinaria de estados de la Action sin redirigir a un estado de error. Para interrumpir la ejecución de la Action, basta con disparar una excepción de tipo ActionProcessInterruption. En el siguiente apartado se verá un uso práctico de esta excepción:

8.3.1.5.1. Paginación sin reejecución de la lógica de negocio

El problema es el siguiente: utilizando la librería Display Tag, cada vez que se produzca un movimiento de página, se solicita una nueva ejecución de la Action que genera el listado, suponiendo esto la reejecución de la lógica de negocio completa (con acceso a datos incluido). La solución a este problema es la que sigue:

• Almacenar siempre las listas de bean a mostrar por el Display Tag en el scope session.

• En la etiqueta del Display Tag, en el atributo “requestUri”, añadir a la URL de la Action un parámetro GET (que no entre en conflicto con alguno que ya utilice la Action).

<display:table name="sessionScope.ListaProductoKey" align="center" id="listProd" pagesize="3" export="false" sort="pag e" requestURI="../../action/viewlistaproducto?paginate =true">

• Extender el método preProcess(). En este método se detectará la existencia del parámetro

definido y, en tal caso, se disparará una ActionProcessInterruption. protected void preProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

if (request.getParameter("paginate") != null) { throw new ActionProcessInterruption();

} }

• Otra opción es utilizar una de las Actions que ya vienen con esta funcionalidad implementada, como son “PrincastCRUDAction” y “PrincastListAction”.

Page 101: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 101 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.3.2. Diferentes tipos de PrincastAction

Además de la clase base PrincastAction, en openFWPA se proporcionan otros tipos de Actions. Por un lado están PrincastDispatchAction y PrincastCRUDAction, una generalización de la anterior, y por otro una serie de implementaciones concretas de la PrincastAction tratada en el punto anterior que facilitan el desarrollo de funcionalidades recurrentes en aplicaciones de gestión.

8.3.2.1. Implementaciones concretas

Existen varias clases que tienen una funcionalidad determinada y que pueden ser reutilizadas tal y como están. Estas son:

• PrincastExistAttributeAction • PrincastRemoveAttributeAction • PrincastForwardAction • PrincastParameterAction

A continuación veremos más en detalle cada una de estas cuatro opciones.

8.3.2.1.1. PrincastExistAttributeAction

Esta clase se encarga de verificar la existencia de un atributo en alguno de los scopes o ámbitos (request, session o application) de la aplicación Web. En la propiedad “parameter” del <action-mapping> se indicará el scope y el nombre del atributo a buscar, separados por ";". Por ejemplo: parameter="application;HOURS". Si se quiere buscar el atributo en cualquier scope se utilizará un *. Por ejemplo: parameter="*;HOURS". Si no se especifica alguno de los dos parámetros, se produce un error.

8.3.2.1.2. PrincastRemoveAttributeAction

Esta clase trata de eliminar un atributo dentro de uno de los ámbitos posibles (application, request, session). Si el atributo existe devuelve el control a un ActionForward etiquetado con “success” y, sino, a uno etiquetado con “failure”. Tanto el ámbito como el atributo se pasan en la propiedad parameter de ActionMapping separados por ";" (parameter="application;HORAS").

Page 102: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 102 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para indicar que la búsqueda se realice en todos los ámbitos, el primer parámetro debe ser un asterisco ("*") en lugar del nombre de un ámbito (parameter="*;HORAS"). El atributo sólo será eliminado del primer contexto en el que sea localizado.

8.3.2.1.3. PrincastForwardAction

Acción que redirecciona a la URI relativa al contexto especificada por la propiedad parameter del ActionMapping. Esta clase puede ser usada para integrar la aplicación con otra lógica de negocio de otros componentes implementados como Servlets o páginas JSP, pero manteniendo la funcionalidad del Servlet controlador de Struts (como el procesado de form beans). Para configurar una PrincastAction de este tipo en el fichero struts-config.xml es necesario crear una etiqueta como ésta: <action path="/guardaSuscripcion" type=" es.princast.framework.web.action.PrincastForwardAct ion" name="suscripcionForm" scope="request" input="/ suscripcion.jsp" parameter="/path/a/servlet"/> Que redireccionará el control a la URI relativa al contexto /path/a/servlet .

8.3.2.1.4. PrincastParameterAction

Esta Action busca un parámetro en la request llamado dispatch y usa su valor para recuperar un forward local. Una vez conseguido este forward busca un segundo parámetro en la request cuyo nombre debe ser especificado en la propiedad parameter del ActionMapping. Este valor se concatena con el valor de la propiedad path del forward obtenido con anterioridad. La URI resultante es la que se usa para hacer la redirección. Un ejemplo de la declaración de una PrincastParameterAction de este tipo es: <action path="/menu/busca" type="es.princast.framework.web.action.PrincastPara meterAction" name="menuForm" validate="false" parameter="keyValue">

<forward name="titulo" path="/do/busca/Titulo?titul o=" /> <forward name="autor" path="/do/busca/Autor?autor=" /> <forward name="contenido" path="/do/busca/Contenido ?contenido=" />

</action> Un fragmento de una página JSP que hiciera uso de esto podría ser:

Page 103: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 103 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<html:form action="menu/busca">

Busca artículos por : <html:select property="dispatch">

<html:option value="titulo">Titulo</html:option> <html:option value="autor">Autor</html:option> <html:option value="contenido">Contenido</html:op tion>

</html:select> <html:text property="keyValue" /> <html:submit>Enviar</html:submit>

</html:form> Si el usuario elige Contenido y escribe Java en el campo de texto, el navegador enviará: dispatch=contenido keyValue=Java. Con esta información la PrincastParameterAction busca el forward contenido y concatena el valor de keyValue al path del forward, quedando algo del estilo: /do/busca/Contenido?contenido=Java En los forwards definidos dentro del mapping de la PrincastParameterAction es posible incluir parámetros almacenados en la request utilizando la notación ${<nombre del parámetro>}. La PrincastParameterAction buscará, en el path (definido en el forward) la cadena "${<parámetro>}" y la sustituirá por “<parámetro>=<valor de parámetro>". Si, por ejemplo, el valor del parámetro "Titulo" es "Rambo" y se define la siguiente forward: <forward name=”titulo”

path=”/do/busca?${Titulo}” />. La PrincastParameterAction dirigirá a la siguiente URL: /do/busca?Titulo=Rambo.

8.3.2.2. Actions Compuestas (Dispatch)

En muchas ocasiones interesa tener juntas aquellas acciones que se encargan de tareas relacionadas. Los métodos que se encargan de la ejecución de tales tareas son encapsulados en una misma clase. Para estos casos están pensadas las acciones que se presentan en este apartado:

• PrincastDispatchAction • PrincastCRUDAction.

8.3.2.2.1. PrincastDispatchAction

Esta clase es una especialización de la PrincastAction. Mantiene la misma estructura de máquina de estados que su clase padre pero se puede decir que cada una de las acciones que encapsula dispone de su propia máquina de estados.

Page 104: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 104 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Si por ejemplo queremos encapsular juntas las acciones “update” e “insert” tendríamos: updatePreProcess, updateExecuteActionLogic, etc. - y también insertPreProcess, insertExecuteActionLogic, etc. A pesar de que cada acción pueda tener su propia máquina de estados, puede interesar que las acciones compartan determinada funcionalidad. Para estos casos están los métodos defaultPreProcess, defaultExecuteActionLogic, etc. ¿Cómo identificar los métodos a ejecutar?

A la hora de seleccionar los métodos a ejecutar la PrincastDispatchAction hace uso del valor que se le pasa en el parámetro parameter del ActionMapping asociado. Si lo que queremos es ejecutar los métodos de la máquina de estados asociada a la acción “update”, entonces este parámetro debe ser <action-mapping …… parameter="method" ….. />, donde el valor del parámetro method, será update. Si no se da implementación a alguno de los métodos update<estado_máquina>, por ejemplo updatePreProcess(), la PrincastDispatchAction ejecutará el método defaultPreProcess(). De igual modo ocurre con el resto de métodos. Es posible desacoplar el valor del parámetro del nombre del método. Se pueden establecer mapeos {valor_de_parameter, nombre_de_método} extendiendo el método getMethodKey() de la clase PrincastDispatchAction. La PrincastDispatchAction permite, por defecto, una salida de éxito (success), otra de error (error) para cada método de la Action. Por convenio, en la PrincastDispatchAction, la salida de éxito de un método será un forward cuyo nombre será el mismo que la clave del método. El forward de error equivaldrá al nombre del método concatenado con la cadena “-failure”. Para el forward de advertencia se concatenará la cadena “-warning” al nombre del método. <action path="/customDispatchAction" name="aForm" p arameter="method" type="customDispatchActionBean" validate="false" sc ope="session">

<forward name="method1" path="success.path" /> <forward name="method1-failure" path="failure.form" /> <forward name="method2" path="success.dos.path" /> <forward name="failure" path="failure.path" />

</action> En el ejemplo superior, se está mapeando una Action de tipo PrincastDispatch con dos métodos: method1 y method2. Cuando se ejecute con éxito el método method1, se redireccionará al path: “success.path”. Si hay algún error, la redirección se realizará al path: “failure.form”. Por el contrario, cuando se ejecute el método method2, en caso de éxito la redirección se hará al path: “success.dos.path” y cuando se produzca un error, el path de redirección será: “failure.path” (ya que,

Page 105: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 105 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

aunque no ha sido definido un forward de error específico, se ha definido el forward de error por defecto: “failure”).

39 Esquema de la PrincastDispatchAction del ejemplo

En ocasiones, es necesario que una DispatchAction tenga mayor control sobre las redirecciones (forwards) que debe realizar para cada uno de los métodos de dispatch. Al igual que ocurre con otros métodos de la Action (executeActionLogic(), catchException(), etc.) es posible redefinir los métodos de redirección (findSuccess(), findAlert() y findFailure()). El sistema es exactamente el mismo: prefijar cada método con la clave (MethodKey). Por ejemplo: method1FindSuccess(), method2FindFailure(),

etc. A continuación se muestra el código de un ejemplo de un PrincastDispatchAction, disponible en la aplicación de ejemplo “sampleapp”. public class BusquedaProductos extends PrincastDisp atchAction {

Page 106: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 106 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

/** * El delegate que implementa la lógica para el acc eso a los productos

*/ protected CarritoDelegate carritoDelegate;

//inyeccion de dependencia (/beans/web/action-beans .xml)

/** * Asigna el delegate a utilizar para acceder a los productos */

public void setCarritoDelegate(CarritoDelegate carr itoDelegate) { this.carritoDelegate = carritoDelegate; }

/** * Por defecto, se realizará la búsqueda por nombre */ protected void defaultExecuteActionLogic(ActionMapp ing mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

//Inicializamos el radio para que tenga valor p or defecto "Por Nombre" BusquedaProductosForm bpf = (BusquedaProductosF orm) form; bpf.setDispatch("porNombre"); }

/** * Realiza al búsqueda de productos por nombre */ public void porNombreExecuteActionLogic(ActionMappi ng mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){

BusquedaProductosForm bpf = (BusquedaProduct osForm) form; BusquedaEstandarVO busquedaEstandar = new Busqued aEstandarVO(); busquedaEstandar.setNombre(bpf.getValorCriterio() ); defaultActionlogic(request, busquedaEstandar); }

/** * Lanza la búsqueda de productos por descripción */ public void porDescripcionExecuteActionLogic(Action Mapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){

Page 107: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 107 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

BusquedaProductosForm bpf = (BusquedaProductosFor m) form; BusquedaEstandarVO busquedaEstandar = new Bus quedaEstandarVO(); busquedaEstandar.setDescripcion(bpf.getValorCrite rio()); defaultActionlogic(request, busquedaEstandar);

}

private void defaultActionlogic(HttpServletRequest request, BusquedaEstandarVO busquedaEstandar){

/* Puede ser List o PaginatedList. */ Object listaRetorno = null; /* Paginación. */ BuscadorPaginacionHelper paginacionHelper = new BuscadorPaginacionHelper(); busquedaEstandar = paginacionHelper.paginacionOrdenacionColumna(requ est, busquedaEstandar); busquedaEstandar = paginacionHelper.paginacionOrdenacionDireccion(re quest, busquedaEstandar); busquedaEstandar = paginacionHelper.paginacionPag ina(request, busquedaEstandar); listaRetorno = carritoDelegate.getListaProductoPaginada(busqueda Estandar); Integer numElementos = carritoDelegate.getListaProductoCount(busquedaEst andar); paginacionHelper.setNumeroElementosTotales(listaR etorno, numElementos); //Devolvemos la lista de productos. request.setAttribute(RequestKeys.LISTA_PRODUCTOS, listaRetorno); }

protected void catchException(Exception e, ActionMa pping mapping, ActionForm form, HttpServletRequest request,

HttpServletResponse response) {

Page 108: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 108 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

//En este método se debe tratar la excepción. //Generalemente, se debe redireccionar a una pági na de error. unsetException(request); logger.error("Se ha disparado una excepción busca ndo los productos."); } }

8.3.2.2.2. PrincastLookupDispatchAction

La clase PrincastLookupDispatchAction permite implementar un tipo especial de Dispatch Actions para formularios con más de un botón (submit). Es este escenario, el botón que se utilice para el envío del formulario (submit) será quien determine el método que se ejecutará en la Action. Todas las actions lookup deben manejar formularios que extiendan la clase LookupDispatchForm, ya que será esta clase quien se encargue de gestionar las correspondencias entre los botones del formulario y los claves para seleccionar los métodos de la Action. Para extender LookupDispatchForm se debe implementar el método getButtonKeys(), devolviendo un array que contendrá las posibles claves que se contemplan para seleccionar el método a ejecutar. Por otro lado, el formulario maneja otro array (buttons), del mismo tamaño, con una posición reservada para cada botón. Al enviarse el formulario, el array buttons, tendrá todos sus campos nulos, salvo el correspondiente al botón utilizado para el envío (submit). Para seleccionar el método a ejecutar, se utilizará la clave almacenada, en el array de claves, en la misma posición que el botón activo. En el ejemplo que se muestra a continuación, se presenta un formulario con tres botones "Aceptar", "Volver" y "Cancelar". Cada uno de estos botones ejecuta un método distinto:

• "foo1" para "Aceptar" • "foo2" para "Volver" • "foo3" para "Cancelar"

public class FooLookupForm extends LookupDispatchFo rm {

public String[] getButtonKeys() { return new String[]{"foo1", "foo2", "foo3"};

}

Page 109: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 109 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

} En el ActionForm, basta con ordenar los botones y asignarle una clave a cada uno: foo1, foo2 y foo3. public class FooLookupAction extends PrincastLookup DispatchAction {

protected void foo1ExecuteActionLogic(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //Implementar logica de negocio

}

protected void foo2ExecuteActionLogic(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //Implementar logica de negocio

}

protected void foo3ExecuteActionLogic(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //Implementar logica de negocio

} } Las PrincastLookupDispatchAction, desde el punto de vista de su implementación son exactamente iguales que las PrincastDispatchAction habituales. <html:form action="test">

<html:submit property="buttons[0]" value="Aceptar"/ > <html:submit property="buttons[1]" value="Volver"/> <html:submit property="buttons[2]" value="Cancelar" />

Page 110: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 110 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</html:form> En la JSP cada botón submit se debe asignar, por orden, a una entrada del array "buttons".

8.3.2.2.3. PrincastCRUDAction

Esta Action está pensada para la gestión del ciclo de vida de entidades del modelo de la aplicación. Esta dos Action define los métodos del ciclo de vida de una entidad:

• new. Este método debe precargar los campos necesarios para mostrar el formulario de creación de una nueva entidad.

• retrieve. Este método permitirá recuperar una entidad. • list. Este método debe obtener listados de entidades. • delete. Permite borrar una entidad. • update. Permite actualizar los datos de una entidad. • create. Este método servirá para inserter nuevas entidades.

Page 111: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 111 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

40 Ejemplo de implementación ArticuloCRUDAction

Atención

Para poder utilizar correctamente este tipo de Actions es necesario mapearlas dos veces en el fichero struts-config.xml. Uno de los mapeos tendrá la validación de formularios desactivada (validate = true) y se utilizará para solicitar los métodos que no requieren un formulario: new, retrieve, list y delete. El otro mapeo tendrá la validación activada y se utilizará para los métodos que sí requieren formulario: update y create.

<action path="/productosAction" type="productosActi onBean" input="facturas.listaProductos" validate="false" sc ope="request" name="productoForm">

<forward name="list" path="facturas.listaProductos" />

Page 112: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 112 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<forward name="retrieve" path="facturas.listaProduc tos"/> <forward name="new" path="facturas.listaProductos"/ > <forward name="delete" path="facturas.listaProducto s"/>

</action> <action path="/productosFormAction" type="productos ActionBean" input="facturas.listaProductos" validate="true" sco pe="request" name="productoForm"> <forward name="create" path="facturas.listaProducto s"/> <forward name="update" path="facturas.listaProducto s"/> </action> Estas Action también soportan, además, paginación sin necesidad de reejecutar la lógica de negocio. Basta con incluir en la request el parámetro “paginate”. En el caso de esta Action, al contrario que la PrincastListAction, hay que registrar el objeto que se devuelve para listar, explícitamente en la session.

8.3.2.2.3.1. Validación de Formularios en acciones compuestas

La validación de formularios, en el Framework Struts, redirecciona de forma automática, en caso de error, a una página de “input” definida en el mapeo de la action (en el fichero struts-config.xml). Este sistema tiene una limitación y esta es que las Actions compuestas (DispatchAction) solamente pueden definir una única página de “input” para todos sus métodos. OpenFWPA permite solucionar esta limitación del Framework Struts. Para ello, basta con seguir los siguientes pasos:

• Utilizar el controlador PrincastRequestProcessor. Para ello, es necesario incluir la siguiente definición de controlador en el fichero struts-config.xml:

<!-- Para poner multiples input --> <controller processorClass="es.princast.framework.web.action.Pr incastRequestProcessor" />

• En el mapeo de la action compuesta (DispatchAction) que tiene más de una entrada, dejar la definición de input vacía.

• Para cada método de la Action, definir un forward utilizando el siguiente convenio de

nombrado: “<nombre del metodo>Input”. <action path="/productosFormAction" type="productos FormAction" parameter="method" validate="true" scope="request" name="productoForm">

Page 113: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 113 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<forward name="create" path="/action/productosActio n?method=list"/> <forward name="update" path="/action/productosActio n?method=list"/> <forward name="createInput" path="facturas.addProdu cto"/> <forward name="updateInput" path="facturas.detalleP roducto"/>

...

8.3.2.2.4. Actions para Listados

Un subconjunto especial de Actions son aquellas que no tienen ninguna lógica de negocio especial. Su único objetivo es obtener un conjunto de objetos para ser mostrados. En función de si el listado se mostrará en una página HTML o en un PDF, se utilizará la PrincastListAction o la PrincastPDFReportAction.

41 Esquema de las Actions para los listados

Page 114: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 114 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.3.2.2.4.1. PrincastListAction

Esta Action permite realizar paginación sin necesidad de reejecutar la lógica de negocio (problema del Display Tag). Por tanto, si una Action tiene únicamente como propósito obtener un listado, se puede utilizar la PrincastListAction. No hace falta sobrescribir ningún método del ciclo de vida de esta Action, basta con implementar el método getContentList() y devolver el objeto (o colección de objetos) que serán mostrados. El objeto devuelto quedará registrado en sesión, bajo la clave que se especifique en el atributo parameter, en el mapeo de ese action, en el fichero struts-config.xml. Esa clave será utilizada por el Display Tag. En caso de que no se especifique ningún valor para el atributo parameter se disparará una excepción de tipo PrincastActionProcessException. A continuación vemos parte del código que tendríamos que incluir en la correspondiente tabla: requestURI="../../action/MiAction?paginate=true“

8.3.2.2.4.2. PrincastPDFReportAction

Esta Action permite obtener un listado en formato PDF utilizando las utilidades para generación de informes de openFWPA. Para implementar una “Report Action”, basta con redefinir el método getReport(), devolviendo un objeto proveedor de contenido PDF (PDFProvider), por ejemplo, un objeto PrincastReport o PrincastMultiReport. Habitualmente, los informes compilados (en formato .jasper) se almacenan juntos en una misma carpeta. Para facilitar la carga de los ficheros “.jasper”, la clase PrincastPDFReportAction implementa el método loadReport() que devuelve el InputStream correspondiente al fichero del informe. Este método, supone que todos los informes se encuentran en la misma carpeta (por defecto: /WEB-INF/reports). Para buscar los informes en una carpeta distinta, se debe sobrescribir el método getRelativePathToReportFolder().

Page 115: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 115 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

42 Path de la carpeta reports configurada por defecto

Page 116: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 116 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

43 Esquema para la clase PrincastPDFReportAction

8.3.2.2.4.3. PrincastDispatchPDFReportAction

Este Action es la versión dispatch de la PrincastPDFReportAction, permite definir varios métodos para obtener el PDFProvider, por ejemplo, si el parámetro pasado al Action es myMethod se ejecutaría el método myMethodGetReport. Para más información, la Sección ”8.3.2.2. Actions Compuestas

(Dispatch)”.

8.3.2.2.4.4. PrincastXMLAction

Este Action permite servir contenido XML. Para servir una respuesta XML, basta con implementar el método getXMLProvider, que retorna un proveedor de contenido XML.

Page 117: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 117 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra un ejemplo de una clase disponible en la aplicación de ejemplo que extiende de la clase “PrincastXMLAction”: public class ProductosRSSAction extends PrincastXML Action { /** * Path de la plantilla velocity a utilizar para generar el contenido RSS */ protected static String TEMPLATE_NAME = "es/princast/sampleapp/web/action/xml/productosR SS.vm"; /** * El delegate que se va a utilizar para acceder a la lista de productos */ protected CarritoDelegate carritoDelegate; /** * Obtiene el delegate a utilizar para acceder a la lista de productos */ public CarritoDelegate getCarritoDelegate() { return this.carritoDelegate; } /** * Asigna un objeto delegate para permitir el acc eso a la lista de * productos */ public void setCarritoDelegate(CarritoDelegate c arritoDelegate) { this.carritoDelegate = carritoDelegate; } protected XMLProvider getXMLProvider(HttpServlet Request request, HttpServletResponse response, ActionForm form, A ctionMapping mapping) { // se crea un velocity provider PrincastVelocityXMLProvider vp =

new PrincastVelocityXMLProvider(TEMPLATE_NAME); // se añade la lista de productos a la url vp.put("listaProducto", this.carritoDelegate.getLi staProducto()); // se añade la url de sindicacion vp.put("url",request.getRequestURL().toString());

Page 118: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 118 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

// por último se retorna el provider return vp; } protected void catchException(Exception e, Actio nMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { //En este método se debe tratar la excepción. //Generalemente, se debe redireccionar a una págin a de error. unsetException(request); this.logger.error("Se ha disparado una excepción o bteniendo el listado de productos."); } } El proveedor de contenido XML, será una clase que implemente el interfaz XMLProvider, el cual, obliga implementar el método writeXML(Writer writer), donde simplemente se escribirá el XML, a servir, como podemos ver en el siguiente ejemplo: /** * Provider que permite escribir contenido XML, gen erable mediante * plantillas Velocity */ public class PrincastVelocityXMLProvider extends Pr incastVelocityProvider implements XMLProvider{

public PrincastVelocityXMLProvider(String templateN ame) { super(templateName); }

/** * Método que vuelca el contenido generado por Vel ocity al writer que * se le pasa como parámetro */ public void writeXML(Writer writer) { merge(writer); } }

Page 119: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 119 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.3.2.2.4.5. PrincastDispatchXMLAction

Este Action es la versión dispatch de la PrincastXMLAction, permite definir varios métodos para obtener el XMLProvider, por ejemplo, si el parámetro pasado al Action es myMethod se ejecutaría el método myMethodGetXMLProvider. Para más información, la Sección ”8.3.2.2. Actions Compuestas

(Dispatch)”.

8.4. Action Forms

OpenFWPA dispone de una clase base para el desarrollo de los beans de formulario. Se trata de la clase PrincastActionForm. Entre las propiedades destacables de esta clase se encuentran:

• mutable. Para evitar que una PrincastActionForm sea rellenada de forma automática al hacer un forward entre diferentes acciones, establezca el valor de mutable a true y asegúrese de que todos los setters comprueban el valor de dicha propiedad (if (isMutable()) this.field = field;).

• locale. propiedad de la clase Locale. Si la instancia de la form es mutable, se le asigna la locale

de sesión de Struts siempre que se llame a reset(). Para actualizar el locale de la sesión debe usarse putSessionLocale().

La ubicación de los beans en openFWPA es, tal y como podemos ver en la siguiente imagen, el directorio “form”:

Page 120: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 120 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

44 Path de la carpeta form

Page 121: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 121 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

De la misma manera que en el Framework de Struts, el mapeo de las Actions Forms se sigue haciendo en el fichero “struts-config.xml”, tal y como veremos en la sección “8.5. Mapeo en el fichero struts-

config.xml”. De todas formas, a continuación mostramos un breve ejemplo de cómo se deben mapear los beans en el fichero “struts-config.xml”. <form-beans>

<form-bean name="confirmForm" type="es.princast.sampleapp.web.form.ConfirmForm" / >

<form-bean name="busquedaProductosForm" type="es.princast.sampleapp.web.form.BusquedaProduc tosForm" />

<form-bean name="carritoForm" type="es.princast.sampleapp.web.form.CarritoForm" / >

<form-bean name="detalleProductoForm" dynamic="true " type="es.princast.framework.web.form.PrincastDynaAc tionForm">

<form-property name="detalle" type="es.princast.sampleapp.business.vo.ProductoV O" /> </form-bean>

<form-bean name="perfilForm" dynamic="true" type="es.princast.framework.web.form.PrincastDynaAc tionForm">

<form-property name="perfil" type="es.princast.sampleapp.business.vo.UserVO" / >

</form-bean> </form-beans> Clase base para el desarrollo de los beans de formulario es “PrincastActionForms”. En cuanto a los métodos disponibles::

• setSessionLocale(Locale). Establece el atributo locale.

• getSessionLocale(). Devuelve el atributo locale.

• setMutable(boolean). Establece el valor del atributo mutable.

• isMutable(). Devuelve el valor del atributo mutable.

Page 122: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 122 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• reset(ActionMapping, HttpServletRequest). Las subclases que deseen resetear el valor de sus atributos deben comprobar el valor de éste atributo (if (isMutable()) ...).

• resetSessionLocale(HttpServletRequest). Cambia el atributo locale al valor que tenga el objeto

locale almacenado en la sesión e la petición en curso bajo la clave Globals.LOCALE_KEY.

• putSessionLocale(HttpServletRequest). Cambia el atributo Globals.LOCALE_KEY de la sesión por el atributo locale o por el Locale por defecto si el atributo locale es null.

• getLocaleDisplay(). Devuelve el Locale del usuario o el Locale por defecto.

• setLocaleDisplay(String). Cambia el atributo locale a un código de lenguaje ISO dado. Recibe

como atributo un String con el código del país.

• isBlank(String). Comprueba si el String que se le pasa es null o la cadena vacía.

• describe(). Devuelve un Map con las propiedades de esta PrincastActionForm. Se usa el método PropertyUtils.describe(). Sobrescriba el método si considera que alguna propiedad no debería ser mostrada de este modo, o si un nombre de una propiedad debería ser cambiado. Este método devuelve las propiedades públicas.

• set(PrincastValueObject). Rellena las propiedades de la clase con las del PrincastValueObject

que se le pasa como parámetro. Se proporciona una implementación vacía de este método para que sea sobrescrito.

• populate(PrincastValueObject). Permite cargar los datos del formulario sobre un Value Object.

Este método recibe como parámetro el Value Object sobre el que se van a cargar los datos. Devuelve una referencia al objeto que contiene todos los datos del formulario.

Para la definición de ActionForms dinámicos, se incluye en openFWPA una clase base: PrincastDynaActionForm. Se incluye además una clase base para los formularios que van a ser utilizados por dispatch actions: PrincastDispatchActionForm. Este tipo de formularios incluyen un campo (method) para seleccionar el método de dispatch que se ejecutará para procesarlo. Las clases para la implementación de formularios se encuentran en el paquete: es.princast.framework.web.form. La clase LookupDispatchForm permite disponer de formularios con más de un botón de submit. Para obtener más información acerca de este tipo de forms, véase el apartado “8.3.2.2.2.

PrincastLookupDispatchAction”.

Page 123: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 123 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra un ejemplo de una clase que extiende de PrincastDispatchActionForm, disponible en la aplicación de ejemplo de openFWPA (sampleapp). public class BusquedaProductosForm extends Princast DispatchActionForm { private static final long serialVersionUID = -4890 101581101937298L; /** * Almacena el criterio de busqueda a utilizar */ protected String dispatch; /** * Clave para la busqueda */ protected String valorCriterio; /** * Constructor del formulario */ public BusquedaProductosForm() { this.dispatch = "porNombre"; } public String getDispatch() { return dispatch; } public void setDispatch(String dispatch) { this.dispatch = dispatch; } public String getValorCriterio() { return valorCriterio; } public void setValorCriterio(String valorCriterio) { this.valorCriterio = valorCriterio; } public void reset(ActionMapping mapping, HttpServl etRequest request){ this.valorCriterio = "";

} }

Page 124: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 124 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

8.4.1. Validación de formularios

OpenFWPA incorpora un sistema de validación de formularios que se utiliza definiendo una serie de reglas de validación en un fichero XML (WEB-INF/validator-rules.xml). En este fichero están definidas las reglas de validación (campos obligatorios, rangos de valores, fechas, direcciones de e-mail, etc.). Se pueden añadir a este fichero nuevas reglas de validación definidas por el programador. A continuación se muestra parte del contenido del fichero “validator-rules.xml” dentro de la aplicación de ejemplo (sampleapp): ... <validator name="required" classname="org.apache.struts.validator.FieldChec ks" method="validateRequired" methodParams="java.lang.Object, org.apache.commons.validator .ValidatorAction, org.apache.commons.validator .Field, org.apache.struts.action.Act ionMessages, org.apache.commons.validator .Validator, javax.servlet.http.HttpServl etRequest" msg="errors.required"/> <validator name="requiredif" classname="org.apache.struts.valid ator.FieldChecks" method="validateRequiredIf" methodParams="java.lang.Object, org.apache.commons.va lidator.ValidatorAction, org.apache.commons.va lidator.Field, org.apache.struts.act ion.ActionMessages, org.apache.commons.va lidator.Validator, javax.servlet.http.Ht tpServletRequest" msg="errors.required"/> ... Para mapear los campos de un formulario (PrincastActionForm), con las reglas de validación, se utiliza el fichero “WEB-INF/validation.xml”. A continuación se muestra un ejemplo del fichero incluido en la aplicación de ejemplo (sampleapp): <form-validation>

Page 125: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 125 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<formset> <form name="confirmForm"> <field property="fecha" depends="required,date" page="1"> <arg0 key="label.fecha"/> <var> <var-name>datePattern</var-name> <var-value>dd/MM/yyyy</var-value> </var> </field> <field property="formaPago" depends="required" p age="1"> <arg0 key="label.formaPago"/> </field> <field property="nombre" depends="required" page ="2"> <arg0 key="label.name"/> </field> <field property="apellido1" depends="required" p age="2"> <arg0 key="label.apellido1"/> </field> <field property="apellido2" depends="required" p age="2"> <arg0 key="label.apellido2"/> </field> <field property="direccion" depends="required" p age="2"> <arg0 key="label.direccion"/> </field> <field property="cp" depends="required" page="2" > <arg0 key="label.cp"/> </field> <field property="provincia" depends="required" p age="2"> <arg0 key="label.provincia"/> </field> </form> </formset> </form-validation> Se valida una PrincastActionForm de nombre confirmForm con dos campos: fecha y formaPago. En ambos casos los campos son obligatorios, y además se indica que el primero es una fecha. Mediante

arg0 se indica qué cadena de texto del fichero ApplicationResources.properties se utilizará para construir el mensaje de error en el caso de que la validación no sea satisfactoria. En este caso son dos cadenas que contienen el nombre de los campos que completarán los mensajes de error para cada una de las reglas de validación que también se encuentran en dicho fichero. Además, en el caso de la validación de fechas se necesita un parámetro adicional indicando el patrón que se utilizará para validar la fecha.

Page 126: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 126 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para mostrar los errores de validación en el cliente se necesita incluir en las páginas JSP el tag <ui:errors/> definido en la tld princast-ui.tld. Para más información sobre las reglas de validación y su utilización, consultar la guía del validador de Struts disponible en la dirección http://struts.apache.org/1.2.4/userGuide/dev_validator.html.

45 http://struts.apache.org/1.2.4/userGuide/dev_validator.html

8.4.1.1. Validaciones de openFWPA

Además de las validaciones incluidas en el Struts Validator, para facilitar algunas de las validaciones más habituales, se incluyen en la distribución de openFWPA algunas reglas de validación:

Page 127: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 127 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• twofields. Dados dos campos, verifica que sean iguales. El nombre segundo campos se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: “secondProperty”. Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.twofields.

• twofiedsdistinct. Dados dos campos, verifica que sean diferentes. El nombre segundo campos

se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: “secondProperty”. Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.twofields.distinct.

• notEmptyArray. Dado un campo compuesto (array), verifica que no sea nulo. Si no se realiza

correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces. properties, bajo la clave: errors.notEmptyArray.

• nif. Valida el formato de un NIF o NIE. Si no se realiza correctamente la validación, se

mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.nif.

• cif. Valida el formato de un CIF (Código de Identificación Fiscal). Si no se realiza

correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces. properties, bajo la clave: errors.cif.

• nie. Valida el formato de un NIE (Número de Identificación de Extranjero). Si no se realiza

correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.nie.

• nifOrNie. Valida que un campo se ajuste al formato de un NIF o un NIE (cualquiera de los dos

es válido). Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.nifOrNie.

• datesMinor. Dadas dos fechas, valida que la primera sea menor estricta que la segunda. El

nombre del campo de la segunda fecha se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: “secondDate”. Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.dates.minor.

• datesMinorOrEqual. Dadas dos fechas, valida que la primera sea menor o igual que la segunda.

El nombre del campo de la segunda fecha se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: “secondDate”. Si no se realiza correctamente la validación,

Page 128: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 128 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.dates.minorOrEqual.

• datesEqual. Dadas dos fechas, valida que sean iguales. El nombre del campo de la segunda

fecha se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: "secondDate". Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.dates.equal.

• datesMajor. Dadas dos fechas, valida que la primera sea mayor estricta que la segunda. El

nombre del campo de la segunda fecha se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: "secondDate". Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.dates.major.

• datesMajorOrEqual. Dadas dos fechas, valida que la primera sea mayor o igual que la segunda.

El nombre del campo de la segunda fecha se debe especificar, en el fichero validation.xml, utilizando una variable de nombre: "secondDate". Si no se realiza correctamente la validación, se mostrará el mensaje de error declarado, en ApplicationRespurces.properties, bajo la clave: errors.dates.majorOrEqual.

8.4.1.2. Implementación de validadores

Para implementar nuevos validadores "ad-hoc" para formularios específicos de las aplicaciones, se deben seguir los siguientes pasos:

• Implementar una clase de validación. Se debe implementar una clase de utilidad que contenga, como métodos estáticos, los métodos de validación. Estos métodos deben tener la siguiente signatura:

public static boolean <nombreValidacion>(Object bea n, ValidatorAction va, Field field, ActionErrors errors, HttpServletReques t request)

El parámetro bean será el formulario a validar y el parámetro field, la definición del campo (obtenida del fichero validation.xml).

Para facilitar la implementación de validadores, se ha incluido en openFWPA la clase base AbstractValidator que puede ser extendida implementando el método validate(). Esta clase sigue el patrón Template Method, es decir, implementa la lógica estándar para el proceso de los campos y de los errores en la validación, quedando a las subclases la responsabilidad de

Page 129: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 129 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

implementar la lógica concreta de validación. Un ejemplo concreto de cómo crear una clase de validadores, utilizando AbstractValidators es:

public class FieldValidations { ... public static final String SECOND_PROPERTY = "sec ondProperty"; ... public static boolean validateTwoFields(Object be an, ValidatorAction va, Field field, ActionMessages errors, HttpServletRe quest request) { return new AbstractValidator() { public boolean validate(Object bean, Validato rAction va, Field field, ActionMessages errors, HttpServl etRequest request){ FormAccessor accessor = new FormAccessor(be an); String value = accessor.getFieldAsString(fi eld); String sProperty2 = field.getVarValue(SECON D_PROPERTY); String value2 = accessor.getFieldAsString(s Property2); if (!GenericValidator.isBlankOrNull(value)) { try { if(FieldComparatorValidatorHelper.disti nct(value, value2)) { throw new ValidatorException(); } // try } catch (Exception e) { logger.warn("Error en la validacion : " + valu e + " y " + value2 + " no son iguales o no se han podido compar ar"); processException(errors, field, request, va, e ); return false; } //catch } // if return true; } // validate }.validate(bean, va, field, errors, request);

Page 130: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 130 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

} ...

• Registrar el validador. Una vez implementados los métodos de validación, se deben registrar en el fichero validation-rules.xml (como cualquier otro validador de Struts).

<validator name="nif" classname="es.princast.framework.web.validator.ids .IFValidations" method="validateNIF" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.ActionMessages, javax.servlet.http.HttpServletRequest" depends="required" msg="errors.nif" > </validator>

8.5. Mapeo en el fichero struts-config.xml

De la misma manera que en el Framework de Struts, el mapeo de las actions se sigue haciendo en el fichero struts-config.xml (fichero que contiene información sobre la configuración de Struts).

Page 131: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 131 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

46 Path del fichero struts-config.xml

Page 132: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 132 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Tal y como se ha hecho en los apartados anteriores, tomaremos como ejemplo el fichero “struts-

config.xml” de la aplicación de ejemplo (sampleapp) para comentar las distintas secciones que se incluyen en este fichero. El primer bloque que nos encontramos es “form-beans” (opcional). Aquí se definen los beans de formulario:

• Clases que heredan de es.princast.framework.web.action.PrincastActionForm, y que sirven para almacenar las propiedades introducidas en formularios enviados mediante peticiones Http. Estos formularios serán utilizados por las acciones.

• Clases que heredan de es.princast.framework.web.action.PrincastDynaActionForm. Sirven

para definir un bean de formulario a través del fichero de configuración sin tener que escribir una clase para ello. Sus propiedades son visibles con métodos get y set de la misma forma que un bean convencional.

<form-beans> <!— PrincastActionForm -->

<form-bean name="confirmForm" type="es.princast.sampleapp.web.form.ConfirmForm" / >

<form-bean name="busquedaProductosForm" type="es.princast.sampleapp.web.form.BusquedaProduc tosForm" />

<form-bean name="carritoForm" type="es.princast.sampleapp.web.form.CarritoForm" / >

<!— PrincastDynaActionForm -->

<form-bean name="detalleProductoForm" dynamic="true " type="es.princast.framework.web.form.PrincastDynaAc tionForm">

<form-property name="detalle" type="es.princast.sampleapp.business.vo.Produc toVO" />

</form-bean>

<form-bean name="perfilForm" dynamic="true" type="es.princast.framework.web.form.PrincastDynaAc tionForm">

<form-property name="perfil" type="es.princast.sampleapp.business.vo.UserVO " />

</form-bean>

Page 133: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 133 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</form-beans> El siguiente conjunto de elementos “global-exceptions”, se utilizan para tratar excepciones que no han sido tratadas en la Action. En el siguiente ejemplo se indica que las excepciones no capturadas del tipo Java.langException, sean reenviadas a la página indicada en el atributo path (en este caso se trata de una definition “carrito.error” disponible en el fichero “tiles-defs.xml”). El mensaje de error que se mostrará en la página de error con el tag <html:errors/>, estará en el fichero de recursos (ApplicationResources.properties) con la clave cuyo valor se indique en el atributo key, que en este caso es “global.princastexception”. Mediante el atributo handler se especifica qué manejador de errores se utilizará para tratar la excepción. En este caso se trata del manejador por defecto de Struts (que en el método execute no realiza nada), pero podría definirse un manejador que heredase de él y sobrescribiese el método execute. Se recomienda utilizar el método catchException() de las acciones para tratar las excepciones y no recurrir a excepciones globales. <global-exceptions> <exception key="global.princastexception" type="jav a.lang.Exception" path="carrito.error" handler="org.apache.struts.act ion.ExceptionHandler" /> </global-exceptions> Se recomienda utilizar el método catchException() de las acciones para tratar las excepciones y no recurrir a excepciones globales. <global-exceptions> <exception key="global.princastexception" type="jav a.lang.Exception" path="carrito.error" handler="org.apache.struts.act ion.ExceptionHandler" /> </global-exceptions> El siguiente bloque “global-forwards” representa los ActionForwards (asociaciones entre nombres lógicos y URIs) disponibles para todas las acciones. Cuando una acción finaliza, devuelve un ActionForward o null. Si la acción no devuelve null, el ActionServlet redirige el control al path que sea devuelto por la ActionForward. <global-forwards> <forward name="welcome" path="/action/viewperfil" / > <forward name="avisolegal" path="/action/avisolega l" />

Page 134: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 134 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<forward name="clearCarrito" path="/action/carrit o?method=clear" /> </global-forwards> En la “action-mappings” sección se definen los mapeos de las acciones que manejará la aplicación. Los parámetros comunes a los diferentes tipos de acciones existentes son:

• path. Path relativo al módulo de la acción, comenzando por el carácter /, y sin la extensión del nombre de archivo si se utiliza ésta para el mapeo (por ejemplo, para un mapeo del tipo accion.do, el path sería /accion).

• type. Nombre de la clase, totalmente calificado, de la acción que procesará las peticiones para

este mapeo. El atributo no es válido si se especifican los atributos forward o include.

• scope. El contexto (request o session) que se utiliza para acceder a los beans de formulario.

• validate. (def. true) Poner a true si el método validate del bean de formulario debe ser llamado antes de llamar a este mapeo.

A continuación se comentarán de forma más detallada los distintos tipos de acciones que maneja el Framework.

• PrincastAction. Clase abstracta de la que deben heredar todas las acciones de openFWPA. A continuación se muestra un ejemplo de mapeo:

<action path="/login" type="es.princast.framework.carrito.actions.LoginAc tion" scope="request" validate="false" input="carrito.login">

<forward name="success" path="/action/viewperfil" r edirect="true" /> <forward name="failure" path="/action/login" redire ct="true" />

</action>

La acción lleva anidadas dos ActionForwards a los que se redirigirá en función de que la acción se haya ejecutado con éxito o no. La sintaxis es similar a la de las Global forwards. En el caso de no encontrar la Forward que devuelve el método execute de la acción local a la propia acción, se buscará la misma a nivel global. Es necesario que a ámbito local o global haya definidos dos forwards success y failure.

Page 135: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 135 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Una acción también puede llevar anidadas excepciones. La sintaxis es la misma que la de las Global Exceptions. En el caso de no tener mapeada una excepción local a la acción, se intentaría buscar a nivel global.

• PrincastDispatchAction. Encapsula diferentes métodos de ejecución de una acción en una misma clase. Para ello, se especifica en el atributo parameter del mapeo de la acción en el fichero struts-config.xml, el nombre del parámetro cuyo valor será el nombre del método que ejecutará la acción.

El siguiente ejemplo muestra el mapeo de una acción que hereda de PrincastDispatchAction. La acción ejecutará el método cuyo nombre se le pase en el parámetro method.

<action path="/carrito" parameter="method" type="es.princast.framework.carrito.actions.Carrito Actions" scope="request" input="carrito.viewcarrito" validat e="false">

<forward name="success" path="carrito.viewcarrito" redirect="true" /> </action>

• PrincastCRUDAction hereda de la PrincastDispatchAction. Está pensada para manejar métodos de creado, consulta, actualizado y borrado (New, Create, Retrieve, List, Update y Delete). Los posibles nombres de los métodos a ejecutar están definidos como constantes en la propia clase:

CREATE_KEY: cuyo valor es create RETRIEVE_KEY: cuyo valor es retrieve UPDATE_KEY: cuyo valor es update DELETE_KEY: cuyo valor es delete NEW_KEY: cuyo valor es new LIST_KEY: cuyo valor es list

• PrincastForwardAction. Redirecciona a la URI relativa al contexto que se especifique en la propiedad parameter del mapeo de la acción. Un ejemplo de utilización de una acción de este tipo es el siguiente:

<action path="/welcome" parameter="carrito.login" s cope="request" validate="false" type="es.princast.framework.web.action.PrincastForw ardAction"/>

Page 136: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 136 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La acción redirecciona a la definición de nombre carrito.login.

• PrincastParameterAction. Busca un parámetro en la request de nombre dispatch y lo usa para

obtener un ActionForward. Una vez conseguido esto, va en busca de un segundo parámetro en la request cuyo nombre debe ser especificado en la propiedad parameter del mapeo de la acción. Este valor se concatena con la URI obtenida de la propiedad path del ActionForward que se buscó con el valor del parámetro dispatch, y se redirecciona a la URI resultante.

• PrincastExistsAttributeAction. Verifica la existencia de un atributo en alguno de los ámbitos

posibles (request, session o application). En la propiedad parameter del mapeo de la acción se le indicará el ámbito y el nombre del atributo a buscar siguiendo la siguiente sintaxis: Parameter=”ambito;ATRIBUTO”. Si se quiere buscar en cualquier ámbito, se especificará el valor *. Si no se especifica alguno de los dos parámetros se produce un error.

parameter="application;HOURS" parameter="*;HOURS"

• PrincastRemoveAttributeAction. Trata de eliminar un atributo en alguno de los ámbitos posibles (request, session o application). Si el atributo existe devuelve el control a un ActionForward instanciado con Tokens.SUCCESS y sino con uno instanciado con Tokens.FAILURE. La sintaxis es idéntica a la de la PrincastExistsAttributeAction.

En el siguiente bloque es “controller”, donde se configura el controlador (RequestProcessor). Se recomienda utilizar los controladores proporcionados por openFWPA (PrincastTilesRequestProcessor o PrincastRequestProcessor). A continuación podemos ver el contenido de esta sección dentro del fichero “struts-

config.xml” disponible en el proyecto de ejemplo “sampleapp”. <action-mappings>

<action path="/avisolegal" parameter="carrito.aviso _legal" type="es.princast.framework.web.action.PrincastForw ardAction" scope="request" validate="false">

</action> <action path="/viewlistaproductopdffwd"

Page 137: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 137 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

type="es.princast.framework.web.action.PrincastForw ardAction" parameter="/action/viewlistaproductopdf"/>

<action path="/logout" type="logout" scope="request ">

<forward name="success" path="/action/viewperfil" redirect="true" /> </action>

<action path="/viewcarrito" parameter="carrito.view carrito" type="es.princast.framework.web.action.PrincastForw ardAction" scope="request" validate="false"> </action>

<action path="/carrito" name="carritoForm" type="ca rrito" scope="request" input="carrito.viewcarrito" validat e="false" parameter="method">

<forward name="success" path="MenuVerCarrito" r edirect="true" /> </action>

<action path="/viewdetalleproducto" name="detallePr oductoForm" input="/index.jsp" type="viewdetalleproducto" scope ="request" validate="false">

<forward name="success" path="carrito.detallepr od" /> </action>

<action path="/viewlistaproducto" input="carrito.li staprod" type="viewlistaproducto" scope="request" validate="false" name="busquedaProd uctosForm">

<forward name="success" path="carrito.listaprod " /> </action>

<action path="/viewperfil" name="perfilForm" input= "/index.jsp" type="viewperfil" scope="request" validate="false">

<forward name="success" path="carrito.viewperfi l" /> </action>

<action path="/confirmar" name="confirmForm" type= "confirmar"

validate="false" scope="session" input="carrito.vie wcarrito"> <forward name="success" path="carrito.confirmpedi do"/>

</action> <action path="/envio" name="confirmForm" type="env io" validate="true"

scope="session" input="carrito.confirmpedido"> <forward name="success" path="carrito.envio"/>

</action>

Page 138: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 138 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<action path="/confirmpedido" name="confirmForm" ty pe="confirmpedido" validate="true" scope="session" input="carrito.envi o">

<forward name="success" path="carrito.confirmado" /> </action>

<action path="/viewlistaproductopdf" type="viewlist aproductopdf" validate="false" scope="request" />

<action path="/viewlistaproductoxml" type="viewlist aproductoxml" alidate="false" scope="request" />

<action path="/buscarProdParameter"

name="busquedaProductosForm" type="es.princast.framework.web.action.PrincastPara meterAction"

scope="request" validate="true" input="carrito.buscarprod" parameter="valorCriterio"> <forward name="porNombre" path="/action/busquedaProductos?method=porNombre " /> <forward name="porDescripcion" path="/action/busquedaProductos?method=porDescri pcion" />

</action> <action path="/busquedaProductos" name="busquedaProductosForm" type="busquedaProductos" scope="request" validate="false" parameter="method"> <forward name="default" path="carrito.buscarpro d" /> <forward name="porNombre" path="carrito.listapr od" /> <forward name="porDescripcion" path="carrito.li staprod" /> </action> </action-mappings> El uso de este controlador permite añadir alguna funcionalidad extra que no implementa el controlador por defecto (por ejemplo, múltiples “input” por action, forwards a entradas de menú, etc.). <controller processorClass="es.princast.framework.web.action.Pr incastRequestProcessor" />

Page 139: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 139 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

El uso de este RequestProcessor limita los posibles mapeos que se pueden hacer sobre el ActionServlet (ver a continuación). Las Actions únicamente se pueden mapear a un path del tipo: “/path/*”. No se permiten mapeos del tipo: “/path/*.do”. La sección “message-resources” indica que fichero contiene los mensajes que mostrará la aplicación. En este caso se trata del ApplicationResources.properties del paquete resources. <message-resources parameter="resources.Application Resources" /> En la sección “plug-in”se indica que plug-ins va a utilizar la aplicación. En primer lugar se indica que se utilizará el validador de Struts, y que las reglas de validación se encuentran en validator-rules.xml y los mapeos entre los formularios y las reglas en validation.xml. <plug-in className="org.apache.struts.validator.Val idatorPlugIn">

<set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/valid ation.xml" />

</plug-in> A continuación se indica que se utilizara tiles, y que las definitions se describirán en el fichero tiles-defs.xml. <plug-in className="org.apache.struts.tiles.TilesPl ugin"> <set-property property="definitions-config"

value="/WEB-INF/tiles-defs.xml" /> <set-property property="moduleAware" value="tru e" /> <set-property property="definitions-parser-vali date" value="true" /> </plug-in> En tercer llugar se indica que se utilizara el Struts Menu y que su configuración residirá en el fichero “menu-config.xml”.

<plug-in className="net.sf.navigator.menu.MenuPlugI n"> <set-property property="menuConfig"

value="/WEB-INF/menu-config.xml"/> </plug-in>

Page 140: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 140 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Y por último se carga el plug-in de Spring dentro de la configuración de Struts. <plug-in className="org.springframework.web.struts. ContextLoaderPlugIn">

<set-property property="contextConfigLocation" value="classpath://beans/**/*-beans.xml"/>

</plug-in>. Si lo deseas, puedes obtener más información sobre el fichero web.xml en http://struts.apache.org/1.x/userGuide/configuration.html.

9. La vista

Esta capa se encarga de mostrar las entidades del modelo al usuario. En openFWPA, se implementa esta capa sobre la tecnología JSP. En esta capa, no debería incluirse lógica de negocio. Por este motivo se recomienda utilizar librerías de etiquetas, que permiten una separación clara entre presentación y lógica de negocio. Es importante recordar que openFWPA se basa en el Framework de Struts, un proyecto de la Apache Software Foundation orientado a la construcción de aplicaciones Web, que implementa la arquitectura Modelo 2 (MVC).

9.1. Hojas de estilo (CSS)

Las aplicaciones J2EE desarrolladas utilizando openFWPA, como por ejemplo la aplicación de ejemplo (sampleapp), centralizan el aspecto en hojas de estilo (CSS), lo que nos permite modificar el aspecto de manera centralizada. Estas hojas de estilo permiten separar las instrucciones de formateo (posición, color, tamaño, etc) del código HTML generado por la aplicación. Esto ofrece una mayor sencillez al desarrollo y una mayor adaptabilidad al cambio - en caso de ocurrir cambio de imagen corporativa, se minimiza el ámbito del cambio unas pocas hojas de estilo.

9.1.1. Hojas de estilo en la aplicación de ejemplo

La aplicación ejemplo (sampleapp) maneja 6 hojas de estilos. Debe tomarse esta implementación como referencia de posicionamiento y formateo de textos, bloques, párrafos, etc. En general, se

Page 141: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 141 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

prohíbe el uso de directrices de estilo dentro del código HTML. Cualquier estilo o posicionamiento de bloques deberá ir contenido en una hoja de estilos. Las hojas de estilo manejadas por la aplicación de ejemplo son:

• general.css. Establece los estilos para los elementos más comunes de una página HTML (enlaces, tablas, celdas, párrafos, listas, textos…)

• position.css. Define el posicionamiento de los bloques <div> dentro de la página. La estructura

de una página se ha definido en base a bloques, de los cuales no todos tienen porque aparecer, según las necesidades de página. Para más información, véase los apartados correspondientes a los layouts tiles.

• princast-ui.css. CSS para el estilo de los componentes de las etiquetas princast para las

páginas.

• tabs.css. Hoja de estilos para el tabbed menu.

• displaytag.css. Hoja de estilos exclusiva para el aspecto de las tablas generadas por el tag displaytag. El displaytag genera listas paginadas.

• carrito.css. Hoja de estilo para la ubicación y formato de componentes específicos de la

aplicación de ejemplo. Estas hojas de estilo están ubicadas en “pages/css”, tal y como se puede ver en la siguiente imagen.

Page 142: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 142 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

47 Path del directorio CSS donde se almacenan las hojas de estilo

Las hojas de estilo son enlazadas a través de la página head.jsp. En caso de necesitar nuevas hojas de estilo, se utilizará este componente para hacerlo, de forma que esta tarea quede totalmente centralizada. El código actual de la página head.jsp es: <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <html:xhtml /> <meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1" /> <!-- Css basicas -->

Page 143: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 143 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<link rel="stylesheet" type="text/css" href="../../ css/general.css" /> <link rel="stylesheet" type="text/css" href="../../ css/position.css" /> <link rel="stylesheet" type="text/css" href="../../ css/princast-ui.css" /> <!-- Css para el menú Tabs --> <link rel="stylesheet" type="text/css" href="../../ css/tabs.css" /> <!-- Css para los listados --> <link rel="stylesheet" type="text/css" href="../../ css/displaytag.css" /> <!-- Css especifica de la aplicacion --> <link rel="stylesheet" type="text/css" href="../../ css/carrito.css" /> Según lo expuesto, el código de las páginas JSP debe reducirse al mínimo imprescindible, obteniendo así un código mucho más claro y mantenible. Ejemplo: código JSP del cuerpo de una página de la aplicación sampleapp: <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-logic" prefix="logic" %> <%@ taglib uri="http://displaytag.sf.net" prefix="d isplay" %> <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> <html:xhtml /> <div id="cuerpo"> <ui:errors/> <ui:box bodyId="productos_box"> <ui:box-caption headingLevel="1"> <bean:message key="productos.box.caption" /> </ui:box-caption> <display:table name="listaProductos" id="listProd"

Page 144: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 144 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

export="false" requestURI="../../../action/viewlistaproducto" summary="Listado de productos" > <display:column titleKey="productos.column.nam e" sortProperty="nombre" sortable="true" > <bean:define id="nombreProducto" name="listProd" property="name" toScope="page"/> <html:link action="/viewdetalleproducto" paramId ="id" paramName="listProd" paramProperty="id" title="<%=\"Visualice el detalle de \" + nombreP roducto%>"> <bean:write name="listProd" property="name" /> </html:link> </display:column> <display:column titleKey="productos.column.des cription" property="description" /> <display:column titleKey="productos.column.bas ePrice" sortProperty="precio" property="basePrice" sor table="true" headerClass="sortable"/> <display:column> <bean:define id="url" name="listProd" property="smallImageURL" /> <bean:define id="nombre" name="listProd" property="name" toScope="page"/> <html:img styleClass="imagen_producto" src="<%=url.toString()%>" alt="<%=\"Im&aacute;gen de \" + nombre%>"/> </display:column> </display:table> </ui:box> <html:img styleClass="carrito_image" src="../../ images/productos.jpg" alt=""/>

Page 145: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 145 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<span id="pdf_link"> <html:link styleClass="enlace_imagen enlace_pdf" action="/viewlistaproductopdf" titleKey="produ ctos.descargaPDF.title"> <bean:message key="productos.descargaPDF"/> </html:link> </span> </div> El código anterior responde a la forma en que se construye un cuerpo de página. No se ha utilizado en ningún caso directrices de estilo o posicionamiento dentro de este código, y en esta forma resulta más claro, donde se atiende únicamente a lo que debe mostrar la página y no a como y dónde debe mostrarlo.

9.2. Composición de las páginas JSP (vistas)

OpenFWPA dispone de plantillas para componer la vista. Para ello hace uso del Framework Tiles ™, el cual permite realizar definiciones (definitions) de páginas ensamblando tiles (término que podría traducirse como azulejo, es decir, son como piezas de un puzzle). Las definitions se describen en el fichero tiles-defs.xml, y cada una de ellas sigue un layout o plantilla (contienen conjuntos de tiles). A continuación se muestra el contenido del fichero “tiles-defs.xml”. <tiles-definitions> <definition name="princast.complexLayout"

path="/pages/tiles/layouts/ComplexLayout.jsp" > <put name="head" value="../head.jsp" /> <put name="cabecera" value="../cabecera.jsp" /> <put name="barra_estado" value="../barra_estado.j sp" /> <put name="menu" value="../menu.jsp" /> <put name="barra_navegacion" value="../barra_nave gacion.jsp" /> <put name="cuerpo" value="../cuerpo.jsp" /> <put name="pie_pagina" value="../pie_pagina.jsp" /> <put name="standards" value="../standards_complia nt.jsp" /> </definition> <definition name="princast.simpleLayout"

path="/pages/tiles/layouts/SimpleLayout.jsp"> <put name="head" value="../head.jsp" /> <put name="cabecera" value="../cabecera.jsp" /> <put name="cuerpo" value="../cuerpo.jsp" /> <put name="pie_pagina" value="../pie_pagina.jsp" />

Page 146: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 146 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<put name="standards" value="../standards_complia nt.jsp" /> </definition> <definition name="princast.menu" path="/pages/tile s/menu.jsp"> <put name="displayer" value="PrincastTabbedMenu"/ > </definition> <definition name="princast.submenu" path="/pages/t iles/menu.jsp"> <put name="displayer" value="PrincastTabbedSubmen u"/> </definition> <definition name="princast.applicationLayout"

path="/pages/tiles/layouts/ApplicationLayout.jsp"> <put name="head" value="../head.jsp" /> <put name="cabecera" value="../cabecera.jsp" /> <put name="menu" value="../menu.jsp"/> <put name="barra_navegacion" value="../barra_nave gacion.jsp" /> <put name="cuerpo" value="../cuerpo.jsp" /> <put name="submenu" value="../submenu.jsp"/> <put name="pie_pagina" value="../pie_pagina.jsp" /> <put name="standards" value="../standards_complia nt.jsp" /> </definition> <definition name="carrito.aviso_legal"

extends="princast.simpleLayout"> <put name="title" value="Aviso legal" /> <put name="cuerpo" value="../aviso_legal.jsp" /> </definition> <definition name="carrito.error" extends="princast .simpleLayout"> <put name="title" value="Error" /> <put name="cuerpo" value="../error.jsp" /> <put name="pie_pagina" value="../pagina_vacia.jsp " /> </definition> <definition name="carrito.viewperfil"

extends="princast.applicationLayout"> <put name="title" value="Información sobre el usu ario" /> <put name="cuerpo" value="../cuerpo_perfil.jsp" / > </definition> <definition name="carrito.listaprod"

extends="princast.applicationLayout">

Page 147: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 147 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<put name="title" value="Lista de productos" /> <put name="cuerpo" value="../cuerpo_listaprod.jsp " /> </definition> <definition name="carrito.buscarprod"

extends="princast.applicationLayout"> <put name="title" value="Buscador de productos" / > <put name="cuerpo" value="../cuerpo_buscarprod.js p" /> </definition> <definition name="carrito.detalleprod"

extends="princast.applicationLayout"> <put name="title" value="Detalle de producto" /> <put name="cuerpo" value="../cuerpo_detalleprod.j sp" /> </definition> <definition name="carrito.viewcarrito"

extends="princast.applicationLayout"> <put name="title" value="Contenido del carrito" / > <put name="cuerpo" value="../cuerpo_carrito.jsp" /> </definition> <definition name="carrito.confirmpedido"

extends="princast.applicationLayout"> <put name="title" value="Confirmar pedido" /> <put name="cuerpo" value="../cuerpo_confirm.jsp" /> <put name="calendar" value="../use_calendar.jsp" /> </definition> <definition name="carrito.envio"

extends="princast.applicationLayout"> <put name="title" value="Datos envío" /> <put name="cuerpo" value="../cuerpo_envio.jsp" /> </definition> <definition name="carrito.confirmado"

extends="princast.applicationLayout"> <put name="title" value="Pedido confirmado" /> <put name="cuerpo" value="../cuerpo_confirmado.js p" /> </definition> </tiles-definitions>

Page 148: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 148 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

En el atributo path se indica que plantilla o layout sigue la definition. En cada elemento put mediante el atributo value se indica la página que se insertará dentro de la tile indicada en el atributo name. Es posible especificar definitions que hereden de otras, de tal forma que solo se modifiquen las páginas de cada una de las tiles que se deseen. Para ello se utiliza el atributo extends, como podemos ver por ejemplo en la última definición que hereda de la princast.applicationLayout, y solo se diferencia de esta en la tile: cuerpo. En la siguiente imagen se muestra la ruta del fichero “WEB-INF/tiles-defs.xml”, donde se incluyen las definiciones anteriores.

Page 149: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 149 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

48 Path del fichero tiles-defs.xml

Page 150: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 150 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Las plantillas utilizadas en las definiciones anteriores se encuentran disponibles en pages/tiles/layouts, y en la aplicación de ejemplo existen tres:

• ComplexLayout.jsp. Layout que sigue el formato de las páginas. Esta es de la forma: ___________________________________ |<cabecera> | |__________________________________| |<barra_navegacion> | |__________________________________| |<barra_estado> | |__________________________________| |<menu>| | | | | | | <cuerpo> | | | | | | | |______ |___________________________| |<pie_pagina> | |__________________________________|

El atributo head para envolver la etiqueta <head> del documento HTML hace más sencillo extender un layout y, a su vez, poder emplear diferentes hojas de estilo.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict .dtd"> <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-tiles" prefix="tiles" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-bean" prefix="bean" %> <html:html locale="es" xhtml="true" lang="es"> <head> <html:base /> <title>

<tiles:getAsString name="title" ignore="true"/> - <bean:message key="welcome.title"/> </title>

<tiles:insert attribute="head" ignore="true" />

Page 151: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 151 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</head> <body> <div id="contenedor"> <!-- Cabecera de la pagina --> <tiles:insert attribute="cabecera" ignore="true" /> <!-- Barra de estado --> <tiles:insert attribute="barra_estado" ignore="tr ue" /> <!-- Barra de navegacion --> <tiles:insert attribute="barra_navegacion" ignore ="true" /> <!-- Menu de navegacion --> <tiles:insert attribute="menu" ignore="true" /> <!-- Cuerpo principal de la página --> <tiles:insert attribute="cuerpo" ignore="true" /> <!-- Pie de página --> <tiles:insert attribute="pie_pagina" ignore="t rue" /> </div> <tiles:insert attribute="standards" ignore="true" /> </body> </html:html>

• SimpleLayout.jsp. Layout más sencillo para mostrar, por ejemplo, paginas como las del aviso legal.

____________________________________ |<cabecera> | |_________________________________ | | | | <cuerpo> | | | |__________________________________| |<pie_pagina> | |__________________________________| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. dtd">

Page 152: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 152 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-tiles" prefix="tiles" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-bean" prefix="bean" %> <html:html locale="es" xhtml="true" lang="es"> <head> <html:base /> <title>

<tiles:getAsString name="title" ignore="true"/> - <bean:message key="welcome.title"/> </title>

<tiles:insert attribute="head" ignore="true" /> </head> <body> <div id="contenedor"> <!-- Cabecera de la pagina --> <tiles:insert attribute="cabecera" ignore="true" /> <!-- Cuerpo de la pagina --> <tiles:insert attribute="cuerpo" ignore="true"/> <!-- Pie de página --> <tiles:insert attribute="pie_pagina" ignore="true " /> </div> <tiles:insert attribute="standards" ignore="true" /> </body> </html:html>

• ApplicationLayout.jsp. Layout para aplicaciones. ______________________________________ | <cabecera> | |_____________________________________| | <barra_estado> | |_____________________________________| |<barra_navegacion> | |_____________________________________| | <cuerpo_pagina> |

Page 153: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 153 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

| _____________________________ | | | <tabs> | | | |_____________________________| | | |<cuerpo> | | | | | | | | | | | | | | | |_____________________________| | |_____________________________________| |<pie_pagina> | |_____________________________________| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. dtd"> <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-tiles" prefix="tiles" %> <html:html locale="es" xhtml="true" lang="es"> <head> <html:base /> <title>

<tiles:getAsString name="title" ignore="true"/> - <bean:message key="welcome.title"/> </title>

<tiles:insert attribute="head" ignore="true" /> </head> <body> <div id="contenedor"> <tiles:insert attribute="cabecera" ignore="true"/ > <!-- Cuerpo de la pagina --> <a name="contenido"></a> <div id="cuerpo_pagina"> <div id="contenido_cuerpo"> <!-- Menu de navegacion (principal) --> <tiles:insert attribute="menu" ignore="true" /> <!-- Submenu de navegacion --> <tiles:insert attribute="submenu" ignore="true" />

Page 154: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 154 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<div id="pie_submenu"></div> <!-- Barra de navegacion --> <tiles:insert attribute="barra_navegacion" ignor e="true" /> <div id="contenido_tab"> <!-- Cuerpo del tab --> <div id="cuerpo_tab"> <!-- Cuerpo principal de la página --> <tiles:insert attribute="cuerpo" ignore="tr ue" /> </div> </div> <!-- Del contenido del cuerpo --> </div> <!-- del cuerpo --> <!-- Pie de página --> <tiles:insert attribute="pie_pagina" ignore="true " /> </div> <tiles:insert attribute="standards" ignore="true" /> </body> </html:html> Para más información sobre tiles consultar el manual de referencia disponible en la dirección http://struts.apache.org/1.x/struts-tiles/.

9.3. Pantalla de error

Existen dos páginas de error llamadas todas ellas error.jsp.

• La alojada bajo el directorio de tiles de la aplicación, tiene el look & feel de las tiles vistas anteriormente.

• La que esta bajo el directorio pages tiene un aspecto más general y se usará cuando no se desee redireccionar a una tile.

La aplicación redirigirá el flujo hacia la página cuando ocurra una excepción global no tratada en ningún objeto Action. El mapeo de las excepciones globales hacia esta página se realiza en el descriptor struts-config.xml, mediante la etiqueta: <global-exceptions> <exception key="global.princastexception" type="java.lang.Exception" path="carrito.error" handler="org.apache.struts.action.ExceptionHandle r" />

Page 155: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 155 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</global-exceptions> El path carrito.error que aparece es una definición de Tiles que incluye a la página error.jsp. <definition name="carrito.error" extends="princast. simpleLayout"> <put name="title" value="Error" /> <put name="cuerpo" value="../error.jsp" /> <put name="pie_pagina" value="../pagina_vacia.jsp" /> </definition> Dependiendo del tratamiento interno que se le dé a la excepción en su construcción, es posible obtener la traza completa (stack trace) de la excepción que ha originado la visualización de la página de errores. Como ejemplo se ha introducido un error en una consulta con la base de datos MySQL local contra la que la aplicación de ejemplo trabaja. El resultado es el siguiente:

49 Ejemplo de traza del error simulado en la aplicación de ejemplo

Además se han añadido páginas de error para los errores de solicitud de páginas HTML, más comunes, como por ejemplo error 403 o 404. Se incluye también una pantalla de error para las páginas JSP que oculta los errores al usuario, pero el desarrollador los puede ver en un comentario HTML, en el código fuente de la página.

9.4. Tablas de paginación

Para la creación de tablas se hace uso de la librería Display Tag (http://displaytag.sourceforge.net/).

Page 156: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 156 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Ilustración 50: http://displaytag.sourceforge.net/1.2/

Esta librería construye una tabla con funcionalidades de paginación, ordenación, etc. a partir de una colección de datos. Display Tag ofrece un conjunto de etiquetas personalizadas (jsp custom tags) que automáticamente se encargan de renderizar la vista. Los datos que mostrará la tabla se buscan en una

colección de objetos que puede estar en cualquiera de los ámbitos JSP:

• pageScope. En el ámbito de página. • requestScope. En el ámbito de request (ámbito por defecto). • sessionScope. En el ámbito de sesión. • applicationScope. En el ámbito de aplicación.

Page 157: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 157 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Los tipos de colecciones que soporta son:

• Collection • Enumeration • Map (los valores se muestran en una fila) • Dictionary (los valores se muestran en una fila) • Array • Iterator • Object con un método iterator()

Cualquier otro objeto se mostrará en una única fila. A continuación se muestra un ejemplo de utilización extraído de la aplicación de ejemplo (sampleapp): ... <%@ taglib uri="http://displaytag.sf.net" prefix="d isplay" %> ... <display:table name="listaProductos" id="listProd" export="false" requestURI="../../../action/viewlistaproducto" summary="Listado de productos"> <display:column titleKey="productos.column.name" sortProperty="nombre" sortable="true" > <bean:define id="nombreProducto" name="listProd" property="name" toScope="page"/> <html:link action="/viewdetalleproducto" paramId ="id" paramName="listProd" paramProperty="id" title="<%=\"Visualice el detalle de \" + nombreP roducto%>"> <bean:write name="listProd" property="name" /> </html:link>

Page 158: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 158 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</display:column> <display:column titleKey="productos.column.descri ption" property="description" /> <display:column titleKey="productos.column.basePr ice" sortProperty="precio" property="basePrice" sortab le="true" headerClass="sortable"/> <display:column> <bean:define id="url" name="listProd" property="smallImageURL" /> <bean:define id="nombre" name="listProd" property="name" toScope="page"/> <html:img styleClass="imagen_producto"

src="<%=url.toString()%>" alt="<%=\"Im&aacute;gen de \" + nombre%>"/> </display:column> </display:table> Se utiliza un atributo registrado en la sesión con la clave “listaProductos”, que contiene una lista de objetos de tipo ProductoVO (es un ValueObject)., que tienen una serie de propiedades que nos permitirán recuperar la información y mostrarlas en las columnas de la tabla, como podemos ver en el ejemplo anterior con el atributo “property”. El atributo titleKey nos permite asignar un nombre a la columna. En este caso se está utilizando la clave "productos.column.name", que se puede encontrar en el fichero “ApplicationResources.properties” (comentado ya en los apartados anteriores), y que contiene el valor “Nombre”. A continuación se muestras los métodos setter de la clase ProductoVO, disponible en la aplicación de ejemplo. public class ProductoVO extends BasePrincastVO { private static final long serialVersionUID = 32570 06553293731123L;

Page 159: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 159 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

...

public int getId() { return id;

}

...

public String getDescription() { return description;

}

...

public String getName() { return name;

}

...

public String getSmallImageURL() { return smallImageURL;

}

...

public double getBasePrice() { return basePrice;

} } En cada iteración por la lista se tiene acceso al elemento actual mediante la referencia “listProd” especificada con el atributo “id” de la etiqueta “display:table”. Para cada registro se mostrarán las columnas:

• Nombre, que además será un enlace a la ficha detalle del producto. • Descripción • Precio • Imagen del producto

El usuario puede ordenar la tabla por nombre de producto o por precio, con sólo pulsar sobre el nombre de la columna (especificado mediante el atributo “sortable” de la “display:columna”).

Page 160: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 160 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

51 Ejemplo de listado de productos de la aplicación de ejemplo

Se puede especificar que el contenido de determinadas columnas vaya a una acción (Action). En este caso se ha hecho con la columna nombre del producto. También es necesario indicarle que Action es la que muestra la tabla para que funcione la ordenación. Los estilos por defecto que se utilizarán en la tabla están contenidos en la hoja de estilos displaytag.css. También pueden personalizarse los estilos mediante los atributos headerClass y styleClass, como se puede ver en el ejemplo anterior. Otro recurso importante para la generación de tablas con Display Tag es el fichero de propiedades displaytag.properties, almacenado en la carpeta resources.

52 Path del fichero displaytag.properties

Page 161: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 161 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Este fichero indicará al motor de generación de las tablas de Display Tag diversos parámetros de configuración y literales de salida de la tabla. También es posible indicar desde este fichero los nombres de los estilos CSS que tomarán los elementos de la tabla. Para más información consultar el propio fichero displaytag.properties en el proyecto Display Tag en http://displaytag.sourceforge.net/displaytag.pdf).

9.5. Creación de menús

9.5.1. Información general

La creación de los menús para las aplicaciones desarrolladas a partir de openFWPA se realizará a través del plugin de Struts denominado Struts-menu. Puede consultarse toda la información referente al proyecto Struts-menu en http://struts-menu.sourceforge.net/. Struts-menu está formado por una librería de clases, una biblioteca de tags y algunos recursos suplementarios, que permiten crear menús en las páginas Web de forma declarativa (mediante un descriptor XML).

Page 162: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 162 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

53 http://struts-menu.sourceforge.net/

Puede integrarse con el sistema de seguridad gestionado por los contenedores Web (usuarios y roles), y admite la posibilidad de personalizar la presentación de los menús a través de objetos llamados Displayers. La release 2.2 no se integra con Tiles, aunque esto no significa que no se puedan usar conjuntamente Tiles y Struts-menu, como se muestra en las aplicaciones de ejemplo. En la documentación ofrecida por la versión 2.2 de Struts-menu se apunta como una posible extensión futura la integración con Tiles, de forma que se puedan leer definiciones de menús desde el fichero tiles-

config.xml. Esto reduciría ligeramente la complejidad del mantenimiento, al no tener entonces que gestionar el fichero descriptor de strusmenu, denominado menu-config.xml En cuanto a seguridad, está totalmente integrado con el sistema de autenticación/autorización en el contenedor Web. Se pueden indicar los roles a los que se les permite el acceso a las opciones del

Page 163: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 163 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

menú. El Framework de generación del menú no presentará en la vista las opciones del menú a las que un usuario no tenga acceso (según el rol de este usuario). Esta es una estrategia recomendable a la hora de generar menús dinámicos en relación a los permisos de usuario.

9.5.2. Definir los menús

La definición de los menús que se renderizarán en las aplicaciones desarrolladas se realizará a través de un fichero descriptor XML “menu-config.xml”, que seguirá estará disponible en el directorio “WEB-INF”, tal y como podemos ver en la siguiente imagen:

Page 164: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 164 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

54 Path del fichero menu-config.xml

Page 165: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 165 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra el contenido del fichero “menu-config.xml” incluido en la aplicación de ejemplo “sampleapp”. <?xml version="1.0" encoding="UTF-8" ?> <MenuConfig> <Displayers> <Displayer name="PrincastTabbedMenu" t ype="es.princast.framework.web.view.menu.PrincastTa bbedMenuDisplayer"/> <Displayer name="PrincastTabbedSubmenu" type="es.princast.framework.web.view.menu.PrincastT abbedSubmenuDisplayer"/> </Displayers> <Menus> <Menu name="MenuIntegrado" title="Menu integrado"

action="/viewperfil"> <Item name="miPerfil" title="Mi perfil" action ="/viewperfil"/> <Item name="listaProductos" title="Lista produ ctos" roles="Citizen,REGISTERED" action="/viewlistapr oducto"/> <Item name="buscarProductos" title="Buscar p roductos" roles="Citizen,REGISTERED" action="/busquedaPro ductos"/> <Item name="verCarrito" title="Ver carrito"

roles="Citizen,REGISTERED" action="/viewcarrito" /> </Menu> <Menu name="MenuMiPerfil" title="Mi perfil" action="/viewperfil"></Menu> <Menu name="MenuListaProductos" title="Lista

productos" roles="Citizen,REGISTERED" action="/viewlistaproducto"></Menu>

<Menu name="MenuBuscarProductos" title="Buscar pr oductos"

roles="Citizen,REGISTERED" action="/busquedaProduct os"></Menu>

Page 166: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 166 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<Menu name="MenuVerCarrito" title="Ver carrito" roles="Citizen,REGISTERED" action="/viewcarrito"></ Menu>

</Menus> </MenuConfig> Se pueden observar dos zonas de elementos principales: los displayers y los menus. En la sección Displayers se incluyen los diferentes tipos de renderización que podríamos usar para presentar los menús en pantalla. La versión 2.2 de Struts Menu provee de 8 tipos diferentes, cada una de ellas ofreciendo sus particularidades en cuanto a visualización y recursos exigidos, como pueden ser hojas de estilos, ficheros properties o ficheros de scripts js para la configuración de los menús. <Displayers> <Displayer name="DropDown" type="net.sf.navigator.displayer.DropDownMenuDispl ayer"/> <Displayer name="Simple" type="net.sf.navigator.displayer.SimpleMenuDisplay er"/> <Displayer name="CoolMenu" type="net.sf.navigator.displayer.CoolMenuDisplayer "/> <Displayer name="CoolMenu4" type="net.sf.navigator.displayer.CoolMenuDisplayer 4"/> <Displayer name="MenuForm" type="net.sf.navigator.example.PermissionsFormMenu Displayer"/> <Displayer name="ListMenu" type="net.sf.navigator.displayer.ListMenuDisplayer "/> <Displayer name="TabbedMenu" type="net.sf.navigator.displayer.TabbedMenuDisplay er"/> <Displayer name="Velocity" type="net.sf.navigator.displayer.VelocityMenuDispl ayer"/> <Displayer name="PrincastTabbedMenu" type="es.princast.framework.web.view.menu.Princast TabbedMenuDisplayer"/>

Page 167: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 167 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<Displayer name="PrincastTabbedSubmenu" type="es.princast.framework.web.view.menu.Princast TabbedSubmenuDisplayer"/> <Displayer name="Velocity" type="net.sf.navigator.displayer.VelocityMenuDispl ayer"/> </Displayers> Además de los 8 Displayers incluidos en la distribución de Struts-menu, openFWPA proporciona dos displayers más: PrincastTabbedMenuDisplayer y PrincastTabbedSubmenuDisplayer, que se explicarán con más detalle en el apartado siguiente. En la sección Menus se definirán los menús realmente. Se creará un elemento Menu por cada menú que se necesite mostrar. Cada menú puede tener una serie de opciones, los Item. A su vez cada item podría tener subitems, y así sucesivamente, definiendo el árbol del menú personalizado, como se muestra en el siguiente ejemplo: <Menu name="MenuUnoPB" title="Ejemplo de uso Struts -menu">

<Item name="GrupoINI" title="Opciones comunes"> <Item name="enlace1" title="Ir al Home" page="/We lcome.do" toolTip="Ir a la página inicial de la aplicación" /> <Item name="enlace2" title="Loging contra Base de Datos" page="/LogonBD.do" toolTip="Logearse a través de BD" />

</Item> </Menu>

9.5.3. Displayers específicos de openFWPA

Como se indicaba en el apartado anterior se han incluido en openFWPA dos nuevos Displayers: • PrincastTabbedMenuDisplayer

• PrincastTabbed-SubmenuDisplayer El objetivo de estos nuevos displayers es doble: por un lado, se pretende disponer de un menú que se integre/adapte fácilmente en el nuevo L&F de la aplicación desarrollada con openFWPA, y por otro, el objetivo es eliminar la necesidad de utilizar tecnologías de cliente como JavaScript y Cookies. Estos dos displayers deben utilizarse conjuntamente para renderizar un único menú.

Page 168: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 168 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• PrincastTabbedMenuDisplayer. Se utilizará para generar el código HTML correspondiente al

menú de primer nivel (en forma de “tabs”). • PrincastTabbedSubmenuDisplayer. Se utilizará para generar el código del submenu (en forma

de lista horizontal de botones). El displayer de openFWPA (PrincastMenuDisplayer) únicamente soporta un nivel de anidamiento de menús. Para que el código HTML generado sea compatible con el estándar XHTML, los caracteres '&' de las URLs deben sustituirse por la entidad XML &amp;. A continuación se muestra una captura de pantalla de la aplicación de ejemplo del carrito (sampleapp), y produce la siguiente vista del menú, en caso de que se muestren todos los menús y en el orden.

55 Ejemplo de menú en la aplicación de ejemplo sampleapp

9.5.4. Enlaces en los menús

El valor que los enlaces del menú pueden adquirir se determina mediante alguno de los siguientes 4 atributos (para los tag <Item> y <Menu>) y con la prioridad indicada:

• location: página JSP o URL

Page 169: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 169 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• page: página JSP. • forward: nombre de algún elemento Forward de Struts (definido en struts-config.xml) • action: nombre de algún elemento Action de Struts (definido en struts-config.xml)

Como norma general, se establecerá el uso de action de forma que Struts tome el control de todas las peticiones de página, o forward en todo caso (por ejemplo para enlazar elementos global-forward de Struts). Se “prohíbe” el uso de location o page para llamar directamente a páginas JSP. Es estrictamente obligatorio seguir el ciclo de petición de Struts, dado que openFWPA instrumentalizará todas las peticiones para ofrecer información de ayuda, control y auditoría de la aplicación en tiempo real a técnicos de sistemas y desarrolladores. Si Struts no toma el control de la petición, los resultados no responderían a lo que realmente se espera, y serían engañosos para la toma de decisiones (memoria disponible, tiempos de respuesta, sobrecarga de la aplicación, etc). Para más información sobre enlaces en los menús, dirigirse a la distribución de Struts-menu 2.0 (versión 2.3) y estudiar el ejemplo de menu-config.xml que provee, donde se podrá ver como se emplean las cuatro posibilidades anteriores.

9.5.5. Integración de Struts-menu con una aplicación Struts

Los pasos necesarios para integrar strus-menu en una aplicación Struts son:

• Añadir la librería struts-menu en el pom.xml del proyecto. En este caso, como podemos ver en el código de ejemplo anterior, ya se ha incluido en el “core” de openFWPA, por lo que no sería necesario incluirla nuevamente.

<dependency> <groupId>struts-menu</groupId> <artifactId>struts-menu</artifactId> <version>2.4.3</version> <exclusions> <exclusion> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> </exclusion> <exclusion> <groupId>commons-digester</groupId> <artifactId>commons-digester</artifactId> </exclusion> </exclusions>

Page 170: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 170 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</dependency>

• Añadir el plug-in de struts-menu al fichero descriptor struts-config.xml <plug-in className="net.sf.navigator.menu.MenuPlugI n"> <set-property property="menuConfig" value="/WEB-IN F/menu-config.xml"/> </plug-in>

• Crear el descriptor XML de las definiciones de menús, menu-config.xml y posicionarlo bajo el directorio /WEB-INF. Se puede tomar como referencia la aplicación ejemplo de Stuts-menu o cualquiera de los descriptores XML del menú de las aplicaciones ejemplo de openFWPA (sampleapp y blankapp).

• En las páginas donde se vayan a crear menús, añadir la declaración de la librería de tags.

<%@ taglib uri="http://struts-menu.sf.net/tag" pref ix="menu" %>

• Añadir el código para renderizar el menú en la página JSP. Ejemplo página “pages/tiles/menu.jsp”:

<menu:useMenuDisplayer name='PrincastTabbedMenu' bundle="org.apache.struts.action.MESSAGE" permissio ns="rolesAdapter"> <menu:displayMenu name="MenuIntegrado"/> <menu:displayMenu name="MenuMiPerfil"/> <menu:displayMenu name="MenuListaProductos"/> <menu:displayMenu name="MenuBuscarProductos"/> <menu:displayMenu name="MenuVerCarrito"/> </menu:useMenuDisplayer>

• Añadir el código para renderizar los submenús. Aunque no haya submenús, esta definición debería realizarse igualmente con el objetivo de facilitar la adición de entradas de submenú. Este código, se añadirá a la página JSP en el lugar donde se desea que aparezca el submenú. Es importante que las entradas declaradas para el menú y el submenú sean las mismas. Ejemplo página “pages/tiles/submenu.jsp”:

<menu:useMenuDisplayer name='PrincastTabbedSubmenu' bundle="org.apache.struts.action.MESSAGE" permissio ns="rolesAdapter"> <menu:displayMenu name="MenuIntegrado"/> <menu:displayMenu name="MenuMiPerfil"/> <menu:displayMenu name="MenuListaProductos"/> <menu:displayMenu name="MenuVerCarrito"/>

Page 171: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 171 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</menu:useMenuDisplayer>

• Copiar la biblioteca de tags struts-menu.tld en “/WEB-INF/tld”, o struts-menu-el.tld si se pretende usar Lenguaje de Expresiones (EL).

9.5.6. La librería de tags struts-menu-el.tld

Se utilizará la versión EL de la librería de tags en las aplicaciones construidas sobre openFWPA, con el objetivo de utilizar lenguaje de expresiones para construir enlaces con parámetros dinámicos que puedan ser manejados por el proceso de petición de páginas.

9.5.7. Uso de la librería de tags en la página menu.jsp

En las aplicaciones ejemplo que se incluyen en openFWPA únicamente se maneja el menú en las páginas “menu.jsp” y “submenu.jsp”. Esto tiene que ver con el hecho de uso de Tiles como motor de renderizado de la vista (ver la sección dedicada a este punto) y la existencia de un menú único para todas las posibles vistas. Ejemplo página “pages/tiles/menu.jsp”: <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-logic" prefix="logic" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-tiles" prefix="tiles" %> <%@ taglib uri="http://struts-menu.sf.net/tag" pref ix="menu" %> <%@ taglib uri="/WEB-INF/tld/princast-date.tld" pre fix="date" %> <html:xhtml /> <!-- GENERACION DE MENU Strus-menu 2.0 (version 3) --> <menu:useMenuDisplayer name='PrincastTabbedSubmenu' bundle="org.apache.struts.action.MESSAGE" permissio ns="rolesAdapter"> <menu:displayMenu name="MenuIntegrado"/> <menu:displayMenu name="MenuMiPerfil"/> <menu:displayMenu name="MenuListaProductos"/> <menu:displayMenu name="MenuVerCarrito"/> </menu:useMenuDisplayer> <div id="fecha"> <date:date /> </div>

Page 172: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 172 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<!-- FIN GENERACION DE MENU Strus-menu 2.0 (version 3) --> En el script se puede observar lo siguiente:

• Uso del TLD struts-menu-el.tld • Uso del displayer TabbedPrincastMenu • Renderizado de 6 menús: MeniIntegrado, MenuPerfil, MenuListaProductos,

MenuBuscarProductos, MenuVerCarrito. Todos ellos se han definido previamente en el fichero XML menu-config.xml.

Además de la página menú.jsp, se debe definir la página submenu.jsp para renderizar los menús de segundo nivel. Esta página, será similar a la página menú.jsp, con la diferencia del displayer a utilizar. <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="http://jakarta.apache.org/struts/ta gs-html" prefix="html" %> <%@ taglib uri="http://struts-menu.sf.net/tag" pref ix="menu" %> <html:xhtml /> <!-- GENERACION DE MENU Strus-menu 2.0 (version 3) --> <menu:useMenuDisplayer name='PrincastTabbedMenu' bundle="org.apache.struts.action.MESSAGE" permissio ns="rolesAdapter"> <menu:displayMenu name="MenuIntegrado"/> <menu:displayMenu name="MenuMiPerfil"/> <menu:displayMenu name="MenuListaProductos"/> <menu:displayMenu name="MenuBuscarProductos"/> <menu:displayMenu name="MenuVerCarrito"/> </menu:useMenuDisplayer> <!-- FIN GENERACION DE MENU Strus-menu 2.0 (version 3) -->

9.5.8. Recursos utilizados por el displayer PrincastTabbedMenu

Este displayer utiliza dos hojas de estilo (general.css y tabs.css). Los PrincastMenuDisplayers son objetos configurables (es decir, implementan el interface ConfigurationListener) y, por lo tanto, pueden ser configurados utilizando el sistema de configuración de openFWPA. El nombre del contexto de configuración utilizado por los displayers incluidos en openFWPA, es “MENU.CONTEXT”. Los atributos configurables de los displayers incluidos se definen en la clase MenuConfigurationKeys, disponible en el core de openFWPA, como se puede ver a continuación:

Page 173: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 173 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

/** * Constante que indica el nombre del parámetro GET por el que se especifica * el nombre del menu activo */ public static final String MENU_ITEM_GET_PARAM = "M ENU.ITEM.GET.PARAM"; /** * Constante que indica el nombre del parámetro GET por el que se especifica * el nombre del menu activo */ public static String SUBMENU_ITEM_GET_PARAM = "SUBM ENU.ITEM.GET.PARAM"; /** * Constante que indica el nombre del identificador CSS que da estilo a la * lista del menu */ public static String CSS_MENU_UL_ID = "CSS.MENU.UL. ID"; /** * Constante que indica el nombre de la clase CSS qu e da estilo al item * activo del menu */ public static String CSS_MENU_ACTIVE_CLASS = "CSS.M ENU.ACTIVE.CLASS"; /** * Constante que indica el nombre de la clase CSS qu e da estilo al Link del * item activo del menu */ public static String CSS_MENU_CURRENT_LINK_CLASS= "CSS.MENU.CURRENT.LINK.CLASS"; /** * Constante que indica el nombre del identificador CSS que da estilo a todo * el DIV donde se encierra el menu */ public static String CSS_MENU_DIV_ID = "CSS.MENU.DI V.ID"; /** * Constante que indica el nombre del identificador CSS que da estilo a la * lista del submenu */ public static String CSS_SUBMENU_UL_ID = "CSS.SUBME NU.UL.ID"; /** * Constante que indica el nombre de la clase CSS qu e da estilo al item

Page 174: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 174 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

* activo del submenu */ public static String CSS_SUBMENU_ACTIVE_CLASS = "CS S.SUBMENU.ACTIVE.CLASS"; /** * Constante que indica el nombre de la clase CSS q ue da estilo al Link del * item activo del submenu */ public static String CSS_SUBMENU_CURRENT_LINK_CLASS = "CSS.SUBMENU.CURRENT.LINK.CLASS"; /** * Constante que indica el nombre del identificador CSS que da estilo al DIV * donde se encierra el submenu */ public static String CSS_SUBMENU_DIV_ID = "CSS.SUBM ENU.DIV.ID"; /** * Constante que indica el nombre del menu que se mo strará por defecto */ public static String DEFAULT_MENU = "DEFAULT.MENU"; /** * Constante que indica el nombre del submenu que se mostrará por defecto * (si procede) */ public static String DEFAULT_SUBMENU = "DEFAULT.SU BMENU";

Page 175: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 175 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

9.5.9. Forwards a entradas de menú

Si se utilizan los displayers proporcionados por el openFWPA (PrincastTabbedMenuDisplayer y subclases), es posible realizar “forwards” a entradas de menú. Si un forward de Struts, ya sea global, o definido en el mapping de una Action tiene como “path” el nombre de una entrada de menú, el Request Processor será capaz de redireccionar al usuario al recurso (página, action, etc) asociado con dicha entrada. Las definiciones siguientes pertenecen al fichero menu-config.xml: <Menu name="MenuIntegrado" title="Menu integrado" a ction="/login"> <Item name="miPerfil" title="Mi perfil" action="/vi ewperfil"/> <Item name="listaProductos" title="Lista productos "

roles="Citizen,REGISTERED" action="/viewlistaproduc to"/>

<Item name="listaProductosPDF" title="Lista product os en PDF" roles="Citizen,REGISTERED" action="/viewlistaproduc topdf"/>

<Item name="verCarrito" title="Ver carrito" roles="Citizen,REGISTERED" action="/viewcarrito"/>

<Item name="salir" title="Salir" action="/logout"/ > </Menu> <Menu name="MenuVerCarrito" title="Ver carrito" rol es="Citizen,REGISTERED" action="/viewcarrito"> </Menu> Definir un forward a una entrada de menú es tan sencillo como sigue: <action path="/carrito" type="es.princast.framework.carrito.web.actions.Car ritoActions" scope="request" input="carrito.viewcarrito" validate="false" parame ter="method">

<forward name="success" path="MenuVerCarrito" redir ect="true" /> </action> También es posible que un forward realice una redirección a una entrada de submenú (menú de segundo nivel), para ello, el path del forward deberá estar compuesto del nombre de la entrada de primer nivel y del nombre de la entrada del submenu separados por el carácter “.” (punto):

• <entrada de menú>.<entrada de submenu>

Page 176: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 176 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Un ejemplo es la siguiente definición: <action path="/carrito" type="es.princast.framework.carrito.web.actions.Car ritoActions" scope="request" input="carrito.viewcarrito" validate="false" parame ter="method">

<forward name="success" path="MenuIntegrado.verCarr ito" redirect="true" />

</action> Para poder realizar forwards a entradas de menú, es necesario utilizar (definiéndolo como “controller” en el fichero struts-config.xml) el request processor: PrincastTilesRequestProcessor. <controller processorClass="es.princast.framework.web.action.Pr incastTilesRequestProcessor" />

9.5.10. Enlaces con parámetros dinámicos

Es posible aumentar las posibilidades de los enlaces generados por struts-menu, añadiendo parámetros por querystring. Además se puede utilizar el lenguaje EL (Lenguaje de Expresiones) de JSTL para acceder a datos más cómodamente, como por ejemplo Beans almacenados en la sesión. Como ejemplo, sirva el siguiente scriptlet, donde se genera un Item de menú cuyo enlace dirigirá la aplicación hacia el Action de struts infoUsuario definido en struts-config.xml, y le añadirá un parámetro idUsu cuyo valor será tomado de un Bean llamado user (posiblemente almacenado en el ámbito de session) que tiene una propiedad llamada idusuario. Como consecuencia de todo esto, finalmente se genera una URL que pudiera tener la siguiente forma: http://localhost:8082/plantillaStruts/infoUsuario.do?idUsu=1234 <Item name="seeThisUser" title="Ver usuario conectado" toolTip="Editar la información del usuario actualm ente conectado" action="infoUsuario?idUsu=${user.idusuario}" />

9.6. Internacionalización

OpenFWPA tiene soporte para la internacionalización de aplicaciones. El fichero ApplicationResources.properties contiene los mensajes del idioma por defecto. El fichero ApplicationResources_xx.properties contendrá los mismos mensajes pero en el idioma cuyo código ISO sea xx (por ejemplo ApplicationResources_en.properties para el inglés).

Page 177: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 177 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para más información sobre los códigos de idioma consultar http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Locale.html. Para mostrar los mensajes en la vista puede utilizarse el tag <bean:message

key=”clave.del.mensaje”>, donde clave.del.mensaje es la clave en el fichero properties del mensaje a mostrar.

9.7. View Helpers, View Adapters, Acciones

Se encargan de realizar operaciones sobre la capa de lógica de negocio y devuelven los resultados a la vista. La mejor forma de realizar la comunicación entre estas dos capas es la utilización del patrón de diseño Data Transfer Object, también llamado Value Object. Habitualmente, la vista recibirá la información del modelo en forma de Value Objects, pero no conocerá como se han creado. Para ello se recomienda utilizar el patrón Business Interface. Este patrón consiste en escribir un interfaz con los métodos de negocio de las entidades (en la capa de negocio), y posee la ventaja de:

• Independizar las operaciones de su implementación • Permitir la reutilización de las operaciones entre distintas presentaciones (interfaz Web, interfaz

Web services, etc). Todos los Value Objects han de implementar la interfaz PrincastValueObject. Un tipo muy habitual de acciones son aquellas que proveerán a la vista de un conjunto de objetos (Value Objects) que serán mostrados en forma de lista. OpenFWPA, contiene una clase de ayuda (ListViewHelper) para facilitar esta tarea. La clase ListViewHelper permite obtener listados y ponerlos a disposición de la aplicación a través de la session (HttpSession). Para obtener el listado a mostrar, se utilizan proveedores de contenido (interface ListContentProvider). Un proveedor de contenido es cualquier objeto (un DAO, un Business Delegate, etc) que pueda proporcionar una lista de Value

Objects a la vista.

Page 178: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 178 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

56 List View Helper

En el diagrama anterior “List View Helper” se puede ver la estructura de las clases explicadas en el párrafo anterior. Existen dos formas de utilizar la clase ListViewHelper:

• Dinámica. Es más adecuada cuando se espera que el ListViewHelper vaya a tener un elevado nivel de demanda. Esta forma de uso requiere crear una instancia de la clase ListViewHelper pasando, al constructor, el ListContentProvider que se va a utilizar cada vez que se le solicite un listado. Una vez creada la instancia se podrá utilizar siempre ese objeto.

ListViewHelper helper = new ListViewHelper(new Exam pleDAO()); //El helper se puede meter en la session para tener lo disponible. request.getSession(true).setAttribute(“listHelper”, helper); helper.loadDataInSession(“listado”, request, null);

Para ejecutar la carga del listado, se utilizará el método loadDataInSession(), que recibe como parámetros: el nombre del atributo de la session donde se dejará el listado, el objeto request del cual se puede obtener la instancia de la session (HttpSession) donde guardará la lista y un array de objetos que contiene los parámetros que puedan ser necesarios para obtener el listado.

• Estática. Esta forma es similar a la anterior. No es necesario crear una instancia de la clase

ListViewHelper, basta con llamar a la versión estática (static) del método loadDataInSession(), pasándole los mismos parámetros que a la versión dinámica más la instancia del ListContetnProvider que se utilizará para generar la lista.

Page 179: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 179 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

ListViewHelper.loadDataInSession(new ExampleDAO(), “listado”, request, null); El código de los dos ejemplos es equivalente.

9.8. Accesibilidad

Un aspecto que se ha tenido en cuenta en openFWPA es el de la accesibilidad. Podemos definir la accesibilidad como la posibilidad de que un sitio o servicio Web pueda ser visitado y utilizado de forma satisfactoria por el mayor número posible de personas, independientemente de sus propias limitaciones o de las derivadas de su entorno. Para tener en cuenta la accesibilidad en openFWPA se han tenido en cuenta las ‘Directrices de Accesibilidad para el Contenido Web 1.0’. (WCAG 1.0) [http://www.w3.org/TR/WCAG10/]. Las Pautas de Accesibilidad al Contenido Web están formadas por 14 pautas generales divididas en un total de 65 puntos de verificación. Cada punto de verificación tiene asignada una prioridad (1, 2 o 3) que indica cómo afecta a la accesibilidad de un sitio Web si dicho punto de verificación no se cumple. Existen tres niveles de adecuación (A, AA y AAA) que indican el grado de cumplimiento de los puntos de verificación por un determinado sitio Web. Tanto en el nuevo modelo de etiquetas para el diseño de interfaces de usuario como en las aplicaciones distribuidas en openFWPA (appBlank, sampleApp), se ha intentado satisfacer un nivel de adecuación AA [http://www.w3.org/WAI/WCAG1AA-Conformance]. El punto de verificación 3.2 de la prioridad 2 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/] indica que se deben desarrollar documentos que estén validados por las gramáticas formales publicadas. Todo el código de las aplicaciones distribuidas con la openFWPA están escritos siguiendo una gramática formal (identificados mediante !DOCTYPE) y validados con el servicio de validación [http://validator.w3.org/] proporcionado por el W3C [http://www.w3.org/]. En el desarrollo de cualquier aplicación desarrollada utilizando openFWPA, se recomienda validar las páginas JSP con alguna herramienta disponible que verifique que la gramática formal utilizada es correcta.

57 Servicio de validación de gramáticas

Page 180: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 180 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Las aplicaciones distribuidas con openFWPA se han desarrollado utilizando la gramática XHTML 1.0 con el DTD "Strict". Esta gramática da prioridad a la estructura frente a la presentación. Por lo tanto todo lo referente a la maquetación y presentación se debe incluir en las hojas de estilo. En openFWPA todas las hojas de estilos propias han sido validadas con el servicio de validación de CSS [http://jigsaw.w3.org/css-validator/] proporcionado por el W3C [http://www.w3.org/]. De la misma forma que se recomienda validar la gramática utilizada, también se recomienda validar las hojas de estilo.

58 Servicio de validación de hojas de estilo

OpenFWPA también recomienda el uso de alguna herramienta de evaluación automática para comprobar:

• Sintaxis de las páginas, tanto del código HTML como de las hojas de estilo, para verificar que están bien formadas y son válidas.

• Accesibilidad. Estas herramientas permiten identificar algunos de los problemas de

accesibilidad del código HTML (nivel de adecuación) Existen varias herramientas de evaluación automática. De entre todas ellas, openFWPA recomienda la herramienta TAW [http://www.tawdis.net/], desarrollada por la Fundación CTIC [http://www.fundacionctic.org/].

59 TAW – Herramienta de evaluación automática

9.9. Librería de etiquetas para el diseño de interfaces de usuario (UI)

OpenFWPA incorpora una librería de etiquetas para simplificar el desarrollo de la vista. Estas etiquetas se encuentran en diferentes ficheros TLD.

• princast-date.tld. Definición de las etiquetas para renderizar calendarios y fechas. • princast-navigation.tld. Definición de las etiquetas para renderizar la barra de navegación.

Page 181: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 181 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• princast-ui.tld. Definición de las etiquetas para renderizar componentes gráficos en general. • princast-util.tld. Definición de las etiquetas de propósito general o de utilidad.

Estas librerías de etiquetas se almacenan en el directorio “WEB-INF/tld”, tal y como se puede ver en la siguiente imagen:

Page 182: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 182 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

60 Path del directorio TLD

Page 183: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 183 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

9.9.1. Selección de fechas y calendarios

No está permitida la introducción de fechas a mano. Es obligatorio utilizar etiquetas específicas para la selección de fechas. En la librería de tags princast-date.tld, incluida en openFWPA, se proporcionan etiquetas para facilitar la labor de introducción de fechas por parte del usuario final de las aplicaciones.

9.9.1.1. Etiqueta <date:calendar/>

La etiqueta <date:calendar/> muestra un calendario desplegable. Para utilizar esta etiqueta debemos incluir el fichero princast-date.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-date.tld" pre fix="date" %> En el siguiente ejemplo se muestra un ejemplo básico de uso de la etiqueta <date:calendar/>. <date:calendar image="../../images/calendario/popca lendar.gif" componentId="fechaPedido" format="dd/mm/yyyy" /> A continuación se verán todos los atributos correspondientes a la etiqueta <date:calendar/>.

• language. Atributo opcional. Idioma en el que se mostrará el calendario. Por defecto 'es'. • enablePast. Atributo opcional. Booleano para indicar si que permite seleccionar una fecha

anterior a la actual. • enableFuture. Atributo opcional. Booleano para indicar si que permite seleccionar una fecha

posterior a la actual. • fixedX. Atributo opcional. Coordenada X en la que se mostrará el calendario. • fixedY Atributo opcional. Coordenada Y en la que se mostrará el calendario. • Image. Atributo opcional. Ruta de la imagen que sirve de icono para desplegar el calendario

(por defecto 'popcalendar.gif'). • imageId. Atributo opcional. Identificador de la imagen que se pulsará para mostrar el

calendario (por defecto 'calgif'). • altText. Atributo opcional. "alt" de la imagen que se pulsará para mostrar el calendario (por

defecto 'Desplegar calendario'). • componentId. Atributo obligatorio. Identificador del campo de formulario que guardará el valor

de la fecha seleccionada en el calendario. • format. Atributo obligatorio. Patrón con el formato en el se devolverá la fecha, como por

ejemplo “dd/mm/yyyy”. • formatCssClass. Atributo opcional. Clase CSS que se aplicará al texto que muestra el formato

de fecha.

Page 184: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 184 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para satisfacer el punto de verificación 1.1 de prioridad 1 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/], se proporciona un texto equivalente si no se puede visualizar la imagen a través del atributo “alt”. Otra pauta que se ha tenido en cuanta es la referente a la desactivación de objetos programados (en este caso, javascript) que viene especificada en el punto de verificación 6.3 de prioridad 1 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/]. Para satisfacer este punto de verificación cuando se utiliza este etiqueta al visualizar la página se muestra al lado de la imagen del calendario un texto que nos informa del formato de fecha utilizado, que coincide con el especificado en el atributo format. El campo de texto asociado al calendario es editable con la finalidad de permitir introducir la fecha en el formato especificado si el javascript esta desactivado.

9.9.1.2. Configuración del calendario

La etiqueta <date:calendar-config/> permite configurar el calendario. Para utilizar esta etiqueta debemos incluir el fichero princast-date.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-date.tld" pre fix="date" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• language. Atributo opcional. Idioma en el que se mostrará el calendario (por defecto 'es'). • enablePast. Atributo opcional. Booleano para indicar si que permite seleccionar una fecha

anterior a la actual (por defecto 'false'). • enableFuture. Atributo opcional. Booleano para indicar si que permite seleccionar una fecha

posterior a la actual (por defecto 'true'). • fixedX. Atributo opcional. Coordenada X en la que se mostrará el calendario (por defecto '-1'). • fixedY. Atributo opcional. Coordenada Y en la que se mostrará el calendario (por defecto '-1'). • startAt. Atributo opcional. Día en el que comienza la semana (0 = domingo y 1 =lunes (por

defecto '1'). • showWeekNumber. Atributo opcional. Booleano que indica si se desea mostrar en número de la

semana (por defecto 'false'). • showToday. Atributo opcional. Booleano que indica si se desea resaltar la fecha actual (por

defecto 'true'). • imgDir. Atributo opcional. Ruta al directorio donde se encuentran las imágenes que necesita el

calendario (por defecto '/'). • dayName. Atributo opcional. Nombres de los días de la semana (No suele usarse y se deja que

sea el fichero de scripts quien lo gestione). • scriptFile. Atributo Obligatorio. Ruta al fichero JS necesario para mostrar el calendario (por

defecto 'calendar.js').

Page 185: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 185 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Hay que tener en cuenta que las dos etiquetas anteriores se utilizan de forma conjunta. Para que la visualización del calendario sea correcta en todos los navegadores, la etiqueta <date:calendar-

config>, debe definirse dentro de la sección HEAD de la página HTML. La forma más correcta de incluir la etiqueta de configuración del calendario es utilizar Tiles, tal y como se muestra en el ejemplo siguiente: <head> <html:base /> <meta http-equiv="Content-type" content="text/html ; charset=ISO-8859-1" /> <link rel="stylesheet" type="text/css" href="css/l ogin05.css" /> <link rel="stylesheet" type="text/css" href="css/p rincast-ui.css" /> <date:calendar-config imgDir="./images/calendario/ " scriptFile="./tiles/scripts/calendar.js"/> <title><bean:message key="welcome.title" /></title > </head> El resultado final es similar al expuesto en la siguiente imagen:

61 Ejemplo de calendario

9.9.1.3. Escribir la fecha actual

La etiqueta <date:date/> permite escribir la fecha actual en el formato:

Page 186: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 186 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

dia_de_la_semana, dia_del_mes / nombre_mes / año Para utilizar esta etiqueta debemos incluir el fichero princast-date.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-date.tld" pre fix="date" %> Un ejemplo de utilización es el siguiente: <date:date/> El formato de la fecha escrita es como sigue: viernes, 30 de Diciembre de 2011 Hay que tener en cuenta que el idioma en el que se visualiza la fecha es el seleccionado en el navegador. Esta etiqueta identifica el cambio de idioma para satisfacer el punto de verificación 4.1 de prioridad 1 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/]. Para especificar el cambio de idioma se utiliza el atributo lang y el código de idioma [http://www.oasis-open.org/cover/iso639a.html] correspondiente.

9.9.2. Barra de navegación

OpenFWPA incluye una barra de navegación que muestra, en cada página la ruta de acceso a la misma y contiene enlaces a todas las entradas de menú pulsadas anteriormente, ya sean entradas de menú o submenú, es decir, es independiente de la jerarquía de menú. La barra de navegación es gestionada por un objeto PrincastNavigationBar, almacenado en la session, bajo la entrada de nombre: es.princast.framework.web.view.navigation.NavigationBar. Además, la barra de navegación es un objeto configurable a través del sistema de configuración centralizado de openFWPA (es decir, implementa el interface ConfigurationListener. La barra de navegación toma los parámetros del contexto de configuración: “NAVIGATION.CONTEXT”. Los parámetros que configuran la barra de navegación son:

• DEFAULT.ITEM.NAME. Indica el nombre por defecto que se generará al crear la barra de navegación. Este será el primer item de la barra, por ello, su valor por defecto es “Inicio”.

Page 187: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 187 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• ITEM.SEPARATOR. Cadena de texto que se utilizará como separador de las entradas de la barra de navegación. El valor por defecto es “:”.

9.9.2.1. Generar una barra de navegación

La etiqueta <navigation:navigator/> genera el código HTML para generar una barra de navegación. Para utilizar esta etiqueta debemos incluir el fichero princast-navigation.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-navigation.tl d" prefix="navigation" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Atributo "id" del map dentro del cual ira la barra de navegación (por defecto 'barra_nav').

• name. Campo opcional. Atributo "name" del map dentro del cual ira la barra de navegación

(por defecto 'barra_nav').

• title. Campo opcional. Atributo "title" del map dentro del cual ira la barra de navegación (por defecto 'Barra de navegación').

• titleKey. Campo opcional. Clave en el fichero de recursos de mensajes para el atributo "title"

del map dentro del cual ira la barra de navegación

• cssClass. Campo opcional. Atributo "class" de los enlaces de los elementos que componen la barra de navegación.

• autoCreate. Campo opcional. Flag que indica si es necesario crear la barra de navegación de

forma automática si ésta no existe (por defecto 'true').

• jump. Campo opcional. Nombre del ancho al que saltar para poder saltar la barra de navegación sin tener que avanzar por cada uno de los enlaces que la componen en el caso de navegadores de texto o dispositivos lectores de pantalla o similares (por defecto 'contenido').

• jumpTitle. Campo opcional. Atributo "title" del enlace para poder saltar la barra de navegación

sin tener que avanzar por cada uno de los enlaces que la componen en el caso de navegadores de texto o dispositivos lectores de pantalla o similares (por defecto 'Saltar barra de navegación e ir al contenido').

Page 188: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 188 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• jumpTitleKey. Campo opcional. Clave en el fichero de recursos del atributo "title" del enlace para poder saltar la barra de navegación sin tener que avanzar por cada uno de los enlaces que la componen en el caso de navegadores de texto o dispositivos lectores de pantalla o similares.

• jumpText. Campo opcional. Texto del enlace para poder saltar la barra de navegación sin tener

que avanzar por cada uno de los enlaces que la componen en el caso de navegadores de texto o dispositivos lectores de pantalla o similares (por defecto 'Ir al contenido').

• jumpTextKey. Campo opcional. Clave en el fichero de recursos del texto del enlace para poder

saltar la barra de navegación sin tener que avanzar por cada uno de los enlaces que la componen en el caso de navegadores de texto o dispositivos lectores de pantalla o similares.

• navigationLabel. Campo opcional. Texto que va delante de los elementos de la barra de

navegación (por defecto 'Está usted aquí:').

• navigationLabelKey. Campo opcional. Clave en el fichero de recursos del texto que va delante de los elementos de la barra de navegación.

Esta etiqueta agrupa mediante un objeto de tipo Map todos los enlaces de la barra de navegación. Para satisfacer el punto de verificación 13.6 de prioridad 3 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/] se proporciona un medio de poder saltar el grupo de enlaces. Por otra parte, en cada uno de los enlaces se utiliza la etiqueta title para aportar una descripción al enlace. Se puede ver un ejemplo de utilización de esta etiqueta en la Tile “pages/tiles/barra_navegacion.jsp”: <%@ page errorPage="/pages/errorEnJSP.jsp" %> <%@ taglib uri="/WEB-INF/tld/princast-navigation.tl d" prefix="navigation" %> <div id="barra_navegacion"> <navigation:navigator /> </div>

9.9.3. Etiquetas para componentes gráficos

A continuación se enumeran el grupo de etiquetas de etiquetas que se van a especificar en los siguientes apartados:

• panel. Contenedor de etiquetas (con aspecto visual) • panel-caption. Permite renderizar el caption o título de las etiquetas panel

Page 189: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 189 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• box. Contenedor de etiquetas (con aspecto visual) • box-caption. Permite renderizar el caption o título de las etiquetas box • layout-area. Contenedor de etiquetas (sin aspecto visual) • block-row. Permite renderizar elementos de bloque de tipo fila • block-column. Permite renderizar elementos de bloque de tipo columna

Todos los contenedores de etiquetas tienen la siguiente parte en común:

• Cuerpo. Es el bloque central del contenedor, donde se ubican los componentes. Dentro de este bloque podemos anidar cualquier tipo de etiqueta.

Además de esta parte común, los contenedores de etiquetas "panel" y "box" añaden las siguientes partes:

• Caption. Es la cabecera del contenedor. Muestra una pequeña descripción del cometido de los controles. En la etiqueta "panel" la cabecera se especifica mediante la etiqueta "panel-caption" y en la etiqueta "box" se especifica a través de la etiqueta "box-caption".

• Pie. Es un bloque decorativo que se coloca al final de estos dos contenedores de etiquetas.

En todas las etiquetas se puede personalizar el aspecto visual. Esto se realiza mediante hojas de estilo. Cada etiqueta tiene varios atributos que nos permiten especificar hojas de estilo. Se pueden utilizar las hojas de estilo ya existentes o se pueden crear nuevas hojas de estilo. Al concluir la descripción de este grupo de etiquetas se muestra un ejemplo de utilización.

9.9.3.1. Etiqueta para renderizar Paneles de Componentes para la UI (similares a los fieldset de

HTML)

La etiqueta <ui:panel/> permite renderizar paneles de componentes para la UI . Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. Esta etiqueta es un contenedor de etiquetas. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para mostrar el panel.

Page 190: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 190 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para mostrar el panel (por defecto 'panel').

• bodyId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el cuerpo del panel.

• bodyCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el cuerpo del panel (por defecto 'panel_body').

• footerId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el pie del panel.

• footerCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el pie del panel (por defecto 'panel_footer').

Este componente tiene la posibilidad de añadirle una caption o título, utilizando la etiqueta <ui:panel-caption>

9.9.3.2. Etiqueta para renderiza el caption o título de las etiquetas panel

La etiqueta <ui:panel-caption/> permite renderizar el caption o título de las etiquetas panel. Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el caption del panel.

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el caption del panel (Por defecto 'panel_caption').

• textId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento de encabezado HTML generado que contendrá el texto del caption del panel.

• textCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento de encabezado HTML generado que contendrá el texto del caption del panel (por defecto 'panel_caption_text').

• headingLevel. Campo obligatorio. Nivel del elemento de encabezado que contendrá el texto (1 para renderizar un "h1", 2 para un "h2", etc.)

Esta etiqueta permite especificar el nivel de encabezamiento a través del atributo headingLevel, para satisfacer el punto de verificación 3.5 de prioridad 2 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/] referente a la utilice elementos de encabezado para transmitir la estructura lógica.

Page 191: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 191 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación se muestra el código de ejemplo y el aspecto obtenido al utilizar las dos etiquetas comentadas anteriormente: <ui:panel id="id-panel" bodyId="bodyId-panel">

<ui:panel-caption headingLevel="2"> <bean:message key="envio.datosPersonales.panel .caption" />

</ui:panel-caption> </ui:panel>

62 Ejemplo de uso de etiqueta panel y panel-caption

9.9.3.3. Etiqueta para generar el bloque central de información de una página con un borde

superior y otro inferior

La etiqueta <ui:box/> genera el bloque central de información de una página con un borde superior y otro inferior. Esta etiqueta es un contenedor de etiquetas. Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para mostrar el box.

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para mostrar el box (por defecto 'box').

• bodyId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el cuerpo del box.

• bodyCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el cuerpo del box (por defecto 'box_body').

• borderUpperId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el borde superior del box.

• borderLowerId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el borde inferior del box.

Page 192: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 192 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• borderCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para los bordes superior e inferior del box (por defecto 'box_border').

Este componente tiene la posibilidad de añadirle una caption o título, utilizando la etiqueta: <ui:box-caption>

9.9.3.4. Etiqueta para renderizar el caption o título de las etiquetas box

La etiqueta <ui:box-caption/> permite renderizar el caption o título de las etiquetas box. Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para mostrar el caption del box.

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para mostrar el caption del box (por defecto 'box_caption').

• textId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento de encabezado HTML generado que contendrá el texto del caption del box.

• textCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento de encabezado HTML generado que contendrá el texto del caption del box (por defecto 'box_caption_text').

• headingLevel. Campo obligatorio. Nivel del elemento de encabezado que contendrá el texto (1 para renderizar un "h1", 2 para un "h2", etc.).

Esta etiqueta permite especificar el nivel de encabezamiento a través del atributo headingLevel, para satisfacer el punto de verificación 3.5 de prioridad 2 de las Directrices de Accesibilidad para el Contenido Web 1.0 (WCAG 1.0) [http://www.w3.org/TR/WCAG10/] referente a la utilice elementos de encabezado para transmitir la estructura lógica. A continuación se muestra el código de ejemplo al utilizar las dos etiquetas comentadas anteriormente: <ui:box bodyId="bodyId-box"> <ui:box-caption headingLevel="2"> <bean:message key="envio.datosPersonales.panel.ca ption" /> </ui:box-caption> </ui:box>

Page 193: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 193 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

9.9.3.5. Etiqueta para renderizar un bloque en área determinada de la página sin aspecto visual

La etiqueta <ui:layout-area/> permite renderizar un bloque en área determinada de la página sin aspecto visual. Esta etiqueta es un contenedor de etiquetas. Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para mostrar el área.

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para mostrar el área (por defecto 'layout_area').

• bodyId. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el cuerpo del área.

• bodyCssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el cuerpo del área (por defecto 'layout_area_body').

A continuación se muestra el código de ejemplo al utilizar la etiqueta anterior: <ui:layout-area id="id-layout" bodyId="bodyId-layou t"> ... </ui:layout-area> El HTML generado con esta etiqueta es simplemente una serie de DIVs anidados que actúan como contenedor, tal y como podemos ver en el siguiente código: <div class="layout_area" id="id-layout"> <div class="layout_area_body" id="bodyId-layout"> ... </div> </div>

Page 194: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 194 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

9.9.3.6. Etiqueta para renderizar elementos de bloque de tipo fila

La etiqueta <ui:block-row/> permite renderizar elementos de bloque de tipo fila. Esta tiene que estar contenida dentro de uno de los contenedores vistos anteriormente. Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el block-row.

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el block-row (por defecto 'item_row').

9.9.3.7. Etiqueta para renderizar elementos de bloque de tipo columna

La etiqueta <ui:block-column/> permite renderizar elementos de bloque de tipo columna. Por lo tanto, este etiqueta debe estar contenida dentro de una etiqueta <ui:block-row/>. Para utilizar esta etiqueta debemos incluir el fichero princastui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• id. Campo opcional. Valor que aparecerá en el atributo "id" del elemento HTML generado para el block-column.

• cssClass. Campo opcional. Valor que aparecerá en el atributo "class" del elemento HTML generado para el block-column (por defecto 'item_columna').

Un ejemplo de utilización de las tres etiquetas anteriores puede ser el siguiente: <ui:layout-area> <ui:block-row> <ui:block-column>Elemento 1</ui:block-column> <ui:block-column>Elemento 2</ui:block-column> </ui:block-row> <ui:block-row> <ui:block-column>Elemento 3</ui:block-column> <ui:block-column>Elemento 4</ui:block-column>

Page 195: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 195 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</ui:block-row> </ui:layout-area> El código JSP del ejemplo anterior generaría la siguiente vista:

63 Ejemplo de uso de etiqueta block-row y block-column

OpenFWPA incluye una hoja de estilos denominada "princast-ui.css" que contiene estilos aplicables al modelo de etiquetas para el diseño de interfaces de usuario (UI). Entre todos los estilos disponibles en esta hoja de estilos, se tienen tres tipos de estilos normalmente aplicados a la etiqueta <ui:block-column/>. Estos estilos son los siguientes:

• item_columna. Mantiene el ancho por defecto (100%). • item_dos_columnas. Asigna un ancho del 49.99%. • item_tres_columnas. Asigna un ancho del 33.33%.

Ejemplo de utilización de “item_tres_columnas”: <ui:layout-area> <ui:block-row> <ui:block-column cssClass="item_tres_columnas"> Elemento 1 </ui:block-column> <ui:block-column cssClass="item_tres_columnas"> Elemento 2 </ui:block-column> <ui:block-column cssClass="item_tres_columnas"> Elemento 3 </ui:block-column> </ui:block-row> <ui:block-row> <ui:block-column cssClass="item_tres_columnas"> Elemento 4 </ui:block-column> <ui:block-column cssClass="item_tres_columnas"> Elemento 5

Page 196: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 196 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</ui:block-column> <ui:block-column cssClass="item_tres_columnas"> Elemento 6 </ui:block-column> </ui:block-row> </ui:layout-area>

9.9.4. Notificación de errores <ui:errors>

La etiqueta <ui:errors/> permite visualizar los errores producidos en la validación de un formulario. Hereda de la etiqueta "errors" de Struts, por lo tanto, se aplican todas las peculiaridades que esta última pudiera tener. Además, permite dar formato a los errores mostrados. Otra particularidad, es que esta etiqueta no va a generar mensajes de error duplicados. Para utilizar esta etiqueta debemos incluir el fichero princast-ui.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-ui.tld" prefi x="ui" %> Esta etiqueta es una extensión de la etiqueta Struts: <html:errors/> Los atributos correspondientes a esta etiqueta son los siguientes: bundle. Campo opcional. locale. Campo opcional. name. Campo opcional. property. Campo opcional. cssClass. Campo opcional. Nombre de la clase CSS que dará estilo a los errores (por defecto 'errors') cssId. Campo opcional. Identificador del bloque HTML que contiene los errores Un ejemplo de utilización en un fichero JSP: ... <ui:errors/> ...

9.9.5. Etiquetas de utilidad y propósito general

9.9.5.1. Etiqueta para ocultar o mostrar código en función de un objeto

La etiqueta <util:instanceOf/> permite ocultar o mostrar determinado código de una página en función de si un objeto (en alguno de los ámbitos habituales: request , session, etc.) es instancia de una clase

Page 197: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 197 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

determinada. Para utilizar esta etiqueta debemos incluir el fichero princast-util.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-util.tld" pre fix="util" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• variableName. Campo obligatorio. Nombre de la variable cuyo tipo se va a verificar. • className. Campo obligatorio. Nombre de la clase para verificar.

Esta etiqueta puede ser de utilidad para mostrar mensajes de error diferentes en función de si existe una excepción de un tipo determinado. Por ejemplo: <util:instanceOf variableName="<%=SecurityGlobals.L OGIN_EXCEPTION%>" className="es.princast.framework.facilities.securit y.exceptions.WrongPasswordException"> <div id="errores"> <ul> <li>Validaci&oacute;n incorrecta de NIF/NIE y Clave personal</li> </ul> </div> </util:instanceOf> Recuerda que para utilizar “SecurityGlobals.LOGIN_EXCEPTION” se debe importar en la cabecera de la página JSP la clase correspondiente, tal y como se especifica a continuación. <%@page import="es.princast.framework.web.filter.security.c ommon.SecurityGlobals"%>

9.9.5.2. Etiqueta para generar código en función del rol de usuario (coincidencia)

La etiqueta <util:isAllowed/> permite la generación de código HTML de su cuerpo en función del rol del usuario. En este caso se comprueba que el rol del usuario coincide con algún rol especificado como atributo. Para utilizar esta etiqueta debemos incluir el fichero princast-util.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-util.tld" pre fix="util" %> Los atributos correspondientes a esta etiqueta son los siguientes:

Page 198: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 198 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• role. Campo obligatorio. Lista de valores separados por comas de los roles permitidos. Un ejemplo de utilización en un fichero JSP: <util:isAllowed role=" Citizen"> <bean:message key="profile.greeting" /> </util:isAllowed> En el ejemplo anterior mostrará el mensaje siempre que el usuario tenga el rol Citizen.

9.9.5.3. Etiqueta para generar código en función del rol de usuario (no coincidencia)

La etiqueta <util:isNotAllowed/> permite la generación de código HTML de su cuerpo en función del rol del usuario. En este caso se comprueba que el rol del usuario no coincide con ninguno de los roles especificados como atributo. Para utilizar esta etiqueta debemos incluir el fichero princast-util.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-util.tld" pre fix="util" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• role. Campo obligatorio. Lista de valores separados por comas de los roles no permitidos. Estas dos últimas etiquetas permiten ocultar o mostrar determinado código en función del rol de usuario que se le pasa como parámetro. Un ejemplo de utilización en un fichero JSP: <util:isNotAllowed role=" Citizen"> <bean:message key="profile.greeting" /> </util:isNotAllowed> En el ejemplo anterior mostrará el mensaje siempre que el usuario NO tenga el rol Citizen.

9.9.5.4. Etiqueta para generar código de combos relacionadas entre si

Con el objetivo de mejorar la usabilidad de las aplicaciones de tramitación, openFWPA ha incluido una serie de etiquetas que permiten dotar a las páginas de comportamiento dinámico, siguiendo la filosofía AJAX (Asynchronous JavaScript). Estas etiquetas están basadas en la librería DWR1 (Direct

Web Remoting).

Page 199: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 199 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La etiqueta <util:dwr-select/> permite asociar dos combos de forma fácil y rápida. El contenido de uno de estos campos se carga en función del valor de otro de ellos. Esta etiqueta utiliza la tecnología DWR (Ajax) para la carga dinámica del contenido de cada campo, estableciendo una relación maestro-detalle entre dos combos. Esta etiqueta hereda de <html:select> proporcionada por Struts, por lo tanto, tendrá todos sus atributos (salvo la propiedad "onchange" que es gestionada directamente por la propia etiqueta). Para utilizar esta etiqueta debemos incluir el fichero princast-util.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-util.tld" pre fix="util" %> Los atributos correspondientes a esta etiqueta son los siguientes:

• controller. Atributo obligatorio. Nombre de la función javascript que llama al controlador DWR para cargar el contenido del select detalle.

• detailId. Atributo obligatorio. Id del select detalle. • labelProperty. Atributo opcional. Nombre de la propiedad de la que se tomarán los labels del

select, en los beans devueltos por DWR (por defecto 'label'). • alt. Atributo opcional. • altKey. Atributo opcional. • disabled. Atributo opcional. • indexed. Atributo opcional. • multiple. Atributo opcional. • name. Atributo opcional. • onblur. Atributo opcional. • onclick. Atributo opcional. • ondblclick. Atributo opcional. • onfocus. Atributo opcional. • onkeydown. Atributo opcional. • onkeypress. Atributo opcional. • onfocus. Atributo opcional. • onkeyup. Atributo opcional. • onmousedown. Atributo opcional. • onmousemove. Atributo opcional. • onmouseout. Atributo opcional. • onmouseover. Atributo opcional. • onmouseup. Atributo opcional. • property. Atributo opcional. • style. Atributo opcional. • styleClass. Atributo opcional.

Page 200: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 200 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• styleId. Atributo opcional. • tabindex. Atributo opcional. • size. Atributo opcional. • title. Atributo opcional. • titleKey. Atributo opcional. • value. Atributo opcional.

A continuación, se muestra un ejemplo de cómo se pueden enlazar dos campos SELECT utilizando esta etiqueta: <util:dwr-select controller="MunicipiosController.g etMunicipios" detailId="municipio" property="provincia" styleId=" provincia" styleClass="cajaTexto input_form" size="1"> <html:optionsCollection name="listaProvincias"/> </util:dwr-select> El código JSP del ejemplo anterior generaría la siguiente vista:

64 Ejemplo de uso de etiqueta util:dwr-select

9.9.5.5. Etiqueta para generar código para incluir los js utilizados en DWR

La etiqueta <util:dwr-import/> permite la generación de código HTML para incluir los ficheros JavaScript (js) necesarios para utilizar las etiquetas "dwr-based". Esta etiqueta debe incluirse en las páginas antes de poder utilizar cualquier etiqueta "dwr-based". Para utilizar esta etiqueta debemos incluir el fichero princast-util.tld en la JSP correspondiente. <%@ taglib uri="/WEB-INF/tld/princast-util.tld" pre fix="util" %> Para poder utilizar cualquiera de las etiquetas de openFWPA basadas en DWR, es necesario previamente, importar los scripts necesarios: engine.js, opcionalmente utils.js, y todos los interfaces con el controlador, por ejemplo interface/MunicipiosController.js. <script type="text/javascript" src="../../dwr/engin e.js"></script> <script type="text/javascript" src="../../dwr/util. js"></script> <script type="text/javascript" src="../../dwr/interface/MunicipiosController.js">< /script>

Page 201: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 201 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para facilitar esta tarea, especialmente si se van a utilizar varios controladores diferentes, se ha incluido la etiqueta <util:dwr-import> que se encarga de generar todas las etiquetas <script> que sean necesarias. Los atributos correspondientes a esta etiqueta son los siguientes:

• renderDWRUtil. Atributo opcional. Indica si se debe importar o no el script de utilidades de DWR.

• controllers. Atributo opcional. Lista de controladores DWR (objetos con métodos exportados por DWR) que se van a importar. La lista será una cadena con todos los nombres de controladores separados por espacios o comas.

• dwrBase. Atributo opcional. URL base para la localización de los scripts DWR. Esta URL será relativa a la página JSP donde se escribe la etiqueta y apuntará al serlvet DWR.

A continuación, se muestra un ejemplo de cómo se puede utiliza esta etiqueta para generar los tres script vistos anteriormente: <util:dwr-import dwrBase="../../../dwr" controllers="MunicipiosController"/>

10. Sistema de Inicialización y Arranque

El núcleo de openFWPA se construye sobre un sistema de inicialización que permite definir, de forma declarativa, los componentes que deben ser creados, configurados e iniciados durante el período de arranque de las aplicaciones. Generalmente estos componentes son objetos de utilidad que tienen alcance global a toda la aplicación, como el sistema de logging, de configuración, monitorización, contadores, consola de administración, etc..

Page 202: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 202 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

El Sistema de Inicialización se basa en el Framework IoC Spring (http://www.springframework.org).

65 Estructura del sistema de inicialización y arranque

10.1. Declaración de objetos inicializables

El fichero de arranque de las aplicaciones que utiliza openFWPA: princast-init-script.xml. En este fichero se deben definir los objetos que serán accesibles durante el periodo de inicialización.

Page 203: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 203 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

66 Path del fichero WEB_INF/princast-init-script.xml

La estructura del fichero princast-init-script.xml se ajusta a la DTD de los ficheros de inicialización del Framework Spring (http://www.springframework.org/dtd/spring-beans.dtd). Para definir un objeto, se utilizará la etiqueta <bean>, indicando, como atributos un identificador para dicho objeto y su clase (opcionalmente se puede indicar si es un Singleton). Dentro de la etiqueta <bean> se pueden establecer propiedades de los objetos de forma declarativa utilizando la etiqueta <property> (se considera propiedad de un objeto a todo método que empiece por la cadena “set” y

Page 204: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 204 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

tenga un solo parámetro. Ver documentación oficial de Java Beans de Sun en http://www.oracle.com/technetwork/java/index.html). Este sistema para dar valor a propiedades de métodos se llama “Inversion Of Control (IoC)”. Las propiedades pueden ser valores introducidos directamente (etiqueta <value>), o referencias a otros objetos definidos en el mismo fichero (etiqueta <ref bean=”…”>). ... <bean id="securityRulesPlugin" class="es.princast.framework.web.filter.security.co rp.conf.SecurityRulesConfigurationPlugin"> <constructor-arg> <value>security-rules</value> </constructor-arg> <property name="file"> <value>WEB-INF/princast-security-rules.xml</value > </property> <property name="contexts"> <list> <value>SECURITY</value> </list> </property> </bean> ... <bean id="jmxBasePluginCap" class="es.princast.framework.core.management.config uration.ConfigurationPluginJMXAdapter"> <property name="plugin"> <ref bean="baseConfigurationPlugin"/> </property> </bean> ... Existen muchas otras etiquetas que permiten:

• especificar valores para los parámetros del constructor • asignar colecciones a propiedades de los objetos • definir variables al estilo ANT (${name})

Page 205: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 205 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• etc. Para mas información al respecto consulte la página Web del Framework Spring [http://www.springframework.org].

10.1.1. Variables ${…} en el fichero de inicialización

En el fichero princast-init-script.xml es posible utilizar variables al “estilo ANT”: ${nombre}. Los valores de estas variables se obtienen de un fichero de propiedades. Para poder utilizar este tipo de variables, es necesario incluir, en el propio fichero princast-init-

script.xml, el siguiente bean: <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.Pro pertyPlaceholderConfigurer"> <property name="location"><value>deploy.properties </value></property> </bean> Donde “deploy.properties” es el fichero del que se cargarán los valores de las variables. La ruta de este fichero es relativa al classpath (se encuentra en el directorio resources). Un ejemplo de uso de variables es el que sigue: <bean id="myBean" class="es.princast.framework.exam ples.MyBean” lazy-init="false" singleton="true">

<property name="exampleProp"><value>${PROP}</value> </property> </bean> Suponiendo que en el fichero “deploy.properties” se haya definido la propiedad PROP. Es posible utilizar rutas de fichero absolutas. Para ello, es necesario utilizar la construcción de Spring “FileSystemResources”, tal y como se indica en el siguiente ejemplo: <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.Pro pertyPlaceholderConfigurer"> <property name="location"> <bean class="org.springframework.core.io.FileSyst emResource"> <constructor-arg> <value>c:/deploy.properties</value>

Page 206: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 206 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</constructor-arg> </bean> </property> </bean>

67 Fichero princast-init-script.xml

10.2. Desarrollo de objetos inicializables

Es posible implementar objetos para que sean arrancados de forma automática, durante la inicialización, por openFWPA. Todos los objetos que están definidos en el fichero princast-init-script.xml pueden ser inicializados y arrancados automáticamente. No es necesario que los objetos implementen ningún interfaz específico pero se tendrá en cuenta:

Page 207: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 207 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• Si los objetos implementan el interfaz Configurable, además de ser creados serán configurados de forma automática por el Framework.

• Si los objetos implementan el interfaz Launchable, serán creados de forma automática (ejecutándose cualquier tarea que tengan implementada bajo el método create()).

• Si los objetos implementan el interfaz RegistrableMBean, éstos serán registrados bajo el sistema de gestión JMX.

El sistema de inicialización siempre arranca los siguientes objetos:

• Manager de logging. • Factoría del sistema de control y gestión JMX. ManagementFactory. • Sistema de configuración. FrameworkConfigurator

10.3. Arranque de aplicaciones Web

El componente inicializador de las aplicaciones es: PrincastStartupListener. El startup-listener implementa el interfaz ServletContextListener y, por tanto, debe ser declarado en el fichero web.xml. Además, también se debe declarar un parámetro de contexto (<context-param>) que indique la ruta del fichero de arranque princastinit-script.xml, tal y como se muestra en el siguiente ejemplo: <context-param> <param-name>INIT.SCRIPT.FILE</param-name> <param-value>/WEB-INF/princast-init-script.xml</pa ram-value> </context-param> <listener> <listener-class>

es.princast.framework.web.startup.PrincastStar tupListener </listener-class>

</listener>

10.4. Arranque manual

El arranque automático de los servicios de openFWPA (configuracion, management, etc.) únicamente está operativo en aplicaciones Web (al estar basado en un ServletContextListener). Para cualquier otro tipo de aplicaciones (consola, EJBs, etc.) en las cuales no hay una parte Web disponible, para acceder a los servicios de openFWPA es necesario lanzar la inicialización de forma manual.

Page 208: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 208 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para realizar esta tarea, se incluye la clase PrincastStandaloneInitializer (disponible en el core de OpenFWPA). Esta clase se debe iniciar (utilizando el método estático init()) al arrancarse la aplicación. Durante la ejecución pone a disposición de la aplicación todos los beans declarados en el fichero de inicialización (princast-init.script.xml), a través del PrincastApplicationContext, que se obtiene con el método getInitScriptContext() de PrincastStandaloneInitializer. // INIT_SCRIPT tiene asociada la clave INIT.SCRIPT. FILE utilizada en el // fichero “web.xml” para definer la ruta del fiche ro de inicialización // “/WEB-INF/princast-init-script.xml”, como vimos en el apartado anterior InputStream stream = this.getClass().getClassLoader().getResourceAsStrea m(INIT_SCRIPT); //Default configuration properties Properties props = new Properties(); props.put("myProp", "myValue"); PrincastStandaloneInitializer.init(stream, props); Para finalizar la aplicación se debe llamar al método estático finish(). El método init() también permite también cargar todos los ficheros XML de definición de beans (de Spring) que sean necesarios para la aplicación. Para especificar los ficheros a cargar se indicarán los patrones correspondientes (siguiendo el convenio de nombrado habitual en Spring), teniendo en cuenta que se tomarán relativos al classpath.

11. Sistema de configuración de aplicaciones

Otro de los sistemas del núcleo de openFWPA es el Sistema de Configuración. El sistema de configuración permite, tanto a los componentes de las aplicaciones como del propio Framework, recibir parámetros de configuración de forma completamente transparente, sin necesidad de preocuparse por la forma o el lugar en que éstos están almacenados.

Page 209: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 209 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

68 Estructura del sistema de configuración

El Sistema de Configuración actúa como un almacén centralizado de parámetros de configuración. En la configuración de aplicaciones intervienen los siguientes componentes:

• Plugins de configuración (ConfigurationPlugin). Se trata de objetos que pueden acceder a un almacén de parámetros de configuración, ya sea para únicamente recuperar sus valores, o también para actualizarlos.

• Contextos de configuración. Los contextos son conjuntos de parámetros agrupados por su funcionalidad. Los parámetros agrupados en un mismo contexto sirven, habitualmente, a objetos relacionados entre sí.

• Configurador de aplicaciones (FrameworkConfigurator). Es el componente central del sistema de configuración. Se encarga de cargar los parámetros y repartirlos a los objetos que los necesiten.

• Objetos configurables (Configurable). Este tipo de objetos escuchan eventos en el “Configurador de Aplicaciones” y pueden actualizar su estado a medida que la configuración de la aplicación cambia. Los listeners son, generalmente, objetos de aplicación que necesitan acceder a los parámetros que proporciona el Sistema de Configuración de openFWPA.

Plugins se encargan de leer / escribir parámetros de configuración

Objetos configurables solicitan parámetros de un CONTEXTO

Objetos configurables solicitan los parámetros al Framework Configurator

Los contextos son clasificaciones de parámetros

Los Plugins se gestionan desde la consola JMX

Page 210: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 210 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

11.1. Implementación de los objetos configurables

Para que un objeto pueda acceder a los parámetros del sistema centralizado de configuración de openFWPA:

• Implementar el interface Configurable.

• Registrarse en el configurador: FrameworkConfigurator.

11.1.1. Implementando el interface Configurable

El interface Configurable define una serie de métodos para la gestión del ciclo de vida del objeto configurable. Los tres métodos definidos son, en realidad, métodos callback. Únicamente van a ser utilizados por el sistema de configuración y no se deben invocar directamente desde objetos de la aplicación. Estos métodos son:

• configure(ConfigurationParameters). Se invoca cuando el objeto se configura por primera vez. Cuando se llama a este método, se presupone que el objeto no ha sido configurado con anterioridad. Este método recibe como argumento un conjunto de parámetros de configuración (ConfigurationParameters).

• reconfigure(ConfigurationEvent). Se invoca cuando el valor de algún parámetro que pueda ser relevante para la configuración del objeto, es actualizado (si se actualizan más de un parámetro, en caso contrario, se utiliza el método siguiente). Este método recibe como parámetro un evento de configuración (ConfigurationEvent).

• reconfigure(ConfigurationParameterUpdatedEvent). Reconfigura un objeto configurable ante la actualización de un único parámetro.

En la implementación de estos métodos, el objeto configurable debe obtener, principalmente del conjunto de parámetros (ConfigurationParameters) o del evento (ConfigurationEvent), los datos que necesite para su configuración.

11.1.1.1. Conjunto de Parámetros de Configuración (ConfigurationParameters)

Se trata de un almacén que contiene todos los parámetros de configuración de la aplicación, agrupados en contextos. Es responsabilidad del objeto configurable seleccionar aquellos parámetros que le puedan ser de utilidad.

Page 211: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 211 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Se pueden obtener todos los parámetros de un conjunto utilizando el método getKeys(). Este método devuelve una enumeración (Enumeration) con los nombres (String) de todos los parámetros existentes en el sistema. Otra opción es buscar únicamente los parámetros clasificados bajo un contexto determinado. En este caso, se utilizará el método getKeys(String), pasando como argumento el nombre del contexto cuyos parámetros se quieren enumerar. Para obtener un parámetro del conjunto ConfigurationParameters, se utilizará el método getParameter(String), si se sabe con certeza que el valor del parámetro es una cadena de caracteres, o el método getConfigurationObject(String) si se quiere recuperar un Object genérico. Ambos métodos reciben como argumento el nombre del parámetro a localizar. Utilizando estos métodos, si dos parámetros coinciden en nombre, se devolverá el primero que se encuentre. Para evitar colisiones de nombrado, se pueden utilizar los métodos alternativos: getParameter(String, String) y getConfigurationObject(String, String). A los cuales se les especifica, como primer argumento, el nombre del contexto en el que se quiere buscar el parámetro. public void configure(ConfigurationParameters param s) { String param = params.getParameter(”MY_FOO_KEY_1”) ; if (param != null) { this.fooKey = param; } param = params.getParameter(“FOO_CONTEXT”, “MY_FOO _KEY_2”); if (param != null) { this.fooKey2 = param; } }

11.1.1.2. Eventos de Configuración (ConfigurationEvent)

Los eventos de configuración se disparan cuando se produce una actualización en los valores de los parámetros de configuración. Cuando un evento de configuración se dispara se invocan los métodos reconfigure() de los objetos configurables. Es responsabilidad del desarrollador de los objetos configurables implementar la respuesta que tendrán sus objetos ante determinados eventos. Como vimos anteriormente, el método reconfigure(), son realmente dos métodos:

• reconfigure(ConfigurationEvent). Recibe un evento de configuración de carácter general. No existe una causa concreta que peda disparar este evento: reinicio del sistema, recarga de un

Page 212: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 212 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

fichero de configuración, etc. El objeto event proporciona: nombre del contexto afectado por el evento (getContextName()) y conjunto de parámetros de configuración actualizados (getParameters()).

• reconfigure(ConfigurationParameterUpdatedEvent). Recibe un evento de reconfiguración más

específico que indica la actualización de un único parámetro de configuración. El objeto event, además de la información suministrada por la superclase (ConfigurationEvent), proporciona,: nombre del parámetro actualizado (getParameterName()), valor anterior (getFormerValue()) y nuevo valor (getCurrentValue()).

public void reconfigure(ConfigurationParameterUpdat edEvent event) { if (event.getContext().equals(this.configurationCo netxtName)) { if (event.getParameterName().equals(“MY_FOO_KEY_1 ”)) { this.fooKey = event.getCurrentValue().toString() ; } else if (event.getParameterName().equals(“MY_FO O_KEY_2”)) { this.fooKey2 = event.getCurrentValue().toString( ); } } } public void reconfigure(ConfigurationEvent event) { if (event.getContext().equals(this.configurationCo netxtName)) { this.configure(event.getParameters()); } }

11.1.2. Registro de un objeto en el FrameworkConfigurator

Por último, para que un objeto (que implemente Configurable) pueda ser gestionado por el sistema de configuración, éste debe ser registrado en el configurador de openFWPA. Para registrar un objeto, basta con llamar al método configureMe() del FrameworkConfigurator. public MyClass() { FrameworkConfigurator.getConfigurator().configureM e(this, true); } Este método recibe dos parámetros: el objeto configurable y un valor booleano que indica si el objeto quiere escuchar, o no, eventos de reconfiguración.

Page 213: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 213 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

11.1.3. Ejemplo de clase que implementa la interfaz Configurable

A continuación podemos ver un ejemplo de una clase que implementa la interfaz Configurable, definiendo para ello las tres clases que hemos visto en los apartados anteriores. Esta clase está disponible en la aplicación de ejemplo “sampleapp” dentro de openFWPA. public class AgenciasManager implements Configurabl e { /** * El nombre de la agencia disponible */ private String agencia; /** * El nombre del contexto de configuración que se utiliza para

* obtener el nombre de la agencia oficial */ private static final String AGENCIA = "CARRITO.AGE NCIA"; /** * El logger de la clase */ protected static final Logger logger =

Logger.getLogger(AgenciasManager.class); { FrameworkConfigurator.getConfigurator().configure Me(this, true); } public void reconfigure(ConfigurationParameterUpda tedEvent event) { Debug.trace(this, "Reconfigurando AgenciasManager . Parametro "+event.getParameterName()); if (event.getParameterName().equals(AGENCIA)) { this.agencia = event.getCurrentValue().toString( ); } } public void configure(ConfigurationParameters conf ) { agencia = conf.getParameter(AGENCIA);

Page 214: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 214 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

if (agencia == null) { logger.warn("No se ha definido una agencia..."); } } /** * Obtiene el nombre de la agencia de transporte a utilizar para el

* envío */ public String getAgencia() { return agencia; } public void reconfigure(ConfigurationEvent event) { this.agencia = event.getParameters().getParameter (AGENCIA); } }

11.2. Plugins de configuración

Los plugins de configuración son los componentes que proporcionan los parámetros que maneja el Sistema de Configuración. Un plugin de configuración se encarga de gestionar un único almacén de datos (un fichero, una base de datos, etc.), sin embargo, un plugin puede servir parámetros a varios contextos de configuración. Los plugins de configuración, implementan el interface

ConfigurationPlugin.

11.2.1. Añadir un plugin de configuración

Si una aplicación tiene alguna necesidad de configuración, la mejor opción suele ser definir plugins de configuración específicos. Para ello, es necesario seguir los siguientes pasos:

• Seleccionar, de los tipos de plugins que contiene openFWPA, el más adecuado. • Si no se encuentra ninguno que se ajuste a las necesidades, implementar uno propio. • Escribir los parámetros de configuración en el almacén seleccionado. • Declarar el plugin en el fichero de arranque de la aplicación (princast-init-script.xml). • Opcionalmente, definir un bean manager para la gestión del plugin a través de la consola JMX. • En el propio fichero princast-init-script.xml, registrar el plugin en la declaración del bean

FrameworkConfigurator.

Page 215: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 215 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

11.2.1.1. Declaración de plugins en el fichero de inicialización

Antes de poder utilizar un plugin de configuración es necesario definirlo en el fichero de arranque de la aplicación (princast-init-script.xml). Los plugins de configuración son objetos inicializables de openFWPA (Ver Sección “10.1. Declaración de objetos inicializables”) y se deben definir como beans en el fichero de arranque. <bean id="abstractConfigurationPlugin" abstract="tr ue" class="es.princast.framework.core.configuration.plu gins.PropertiesFileConfigurationPlugin"> <property name="contexts"> <list> <value>SECURITY</value> <value>ROOT.CONTEXT</value> <value>ACTION.CONTEXT</value> <value>MENU.CONTEXT</value> <value>NAVIGATION.CONTEXT</value> <value>JMX.CONTEXT</value> </list> </property> </bean> <!— Hereda del padre el «property name="contexts" ya que aquí no se definen --> <bean id="baseConfigurationPlugin" parent="abstract ConfigurationPlugin"> <constructor-arg><value>basePlugin</value></constr uctor-arg> <property name="file"><value>${base.module.file}</ value></property> <property name="priority"><value>1</value></proper ty> </bean> Los parámetros que se definen en el ejemplo anterior son:

• <constructor-arg><value>pluginId</value></constructor-arg>. (Obligatorio para todos los plugins) Se debe definir, como argumento de constructor, el nombre que identifica al plugin (en este caso: “basePlugin”).

• <property name="priority">. Se trata de la prioridad del plug-in. En caso de que haya varios

plugins que, para un mismo contexto ofrezcan parámetros de igual nombre (es decir, en caso de que haya conflicto de nombres de los parámetros), se tomarán primero los parámetros ofertados por el plug-in de prioridad mas alta (numero más bajo). Si no se establece ningún valor, por defecto, la prioridad de todos los plug-ins es 10 (un valor intermedio).

Page 216: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 216 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La prioridad permite definir jerarquías de plug-ins de configuración. De esta forma, se permite

definir plug-ins a nivel de contenedor (con parámetros comunes a todas las aplicaciones) que

pueden sobrescritos para definir parámetros específicos para cada aplicación.

• <property name="file">. Algunas propiedades se deben definir, o no, en función del tipo de

plugin. En este caso, el plugin PropertiesFileConfigurationPlugin, exige la definición de la property “file”.

• <property name="contexts">. (Obligatorio para todos los plugins) Por ultimo, se debe definir

la lista de contextos a los que el plugin sirve parámetros. En este caso, el plugin sirve parámetros al contexto raíz (ROOT.CONTEXT), al contexto de seguridad (SECURITY), al contexto del sistema de gestión JMX (JMX.CONTEXT), al contexto de las Actions de la aplicación (ACTION.CONTEXT), al contexto de configuración para los menús (MENU.CONTEXT), y al contexto de configuración de la barra de navegación (NAVIGATION.CONTEXT).

Opcionalmente, una vez definido el plugin, se le puede asignar un adaptador JMX de forma que éste pueda ser manejado desde la consola HTML de la aplicación. Si se define un adaptador, será posible, a través de la consola, actualizar o referescar, en caliente, los valores de los parámetros de configuración del plugin (siempre y cuando el plugin soporte estas operaciones). <!-- Sombreros JMX para los módulos --> <bean id="jmxBasePluginCap" class="es.princast.framework.core.management.config uration.ConfigurationPluginJMXAdapter"> <property name="plugin"> <ref bean="baseConfigurationPlugin"/> </property> </bean> <bean id="jmxJaasConfigPluginCap" class="es.princast.framework.core.management.config uration.ConfigurationPluginJMXAdapter"> <property name="plugin"><ref bean="jaasConfigPlugi n"/></property> </bean> El adaptador JMX es otro bean, del tipo: ConfigurationPluginJMXAdapter. Únicamente es necesario indicar la referencia del plugin (utilizando su identificador de bean: <bean id=…) que debe gestionar, al definir la propiedad “plugin”, tal y como se muestra en el ejemplo anterior.

Page 217: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 217 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Para finalizar, es necesario registrar el plugin en la definición del FrameworkConfigurator (que no es más que otro bean en el fichero princast-init-script.xml). Se debe añadir la referencia al plugin en la propiedad: “plugins”. <!-- Gestor de configuracion --> <bean id="configurationManager" class="es.princast.framework.core.configuration.Fra meworkConfigurator" factory-method="getConfigurator" lazy-init="false" singleton="true"> <property name="plugins"> <list> <ref bean="baseConfigurationPlugin"/> <ref bean="globalConfigurationPlugin"/> <ref bean="jaasConfigPlugin"/> <ref bean="securityRulesPlugin"/> </list> </property> </bean>

11.2.1.2. Plugins en openFWPA

En openFWPA se incluyen algunos plugins de configuración listos para ser utilizados. Además, se proporcionan clases para facilitar el desarrollo de plugins por parte de los usuarios.

Page 218: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 218 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

69 Jerarquía de plugins en openFWPA

11.2.1.2.1. Plugins basados en Properties

Los plugins basados en Properties almacenan parámetros como pares {atributo, valor}. En openFWPA se empaquetan dos clases para gestionar este tipo de parámetros:

• PropertiesConfigurationPlugin, para cargar los datos de configuración de un objeto java.util.Properties en memoria.

<bean id="myPropsConfigurationPlugin" class="es.princast.framework.core.configuration.plu gins.PropertiesConfigurationPlugin"> <constructor-arg><value>propsPlugin</value></const ructor-arg> <property name="priority"><value>12</value></prope rty> <property name="properties"> <map> <entry key="PARAMETRO.UNO"> <value>Un valor</value> </entry> <entry key="PARAMETRO.DOS">

ConfigurationPlugin plugins::

BaseConfigurationPlugin

plugins:: PropertiesConfigurationPlugin

plugins:: PropertiesFileConfigurationPlugin

plugins:: ServletConfigurationPlugin

plugins:: ServletContextPlugin

xml:: XMLConfigContentHandler

xml:: XMLConfigurationPlugin

xml:: XMLStringConfigurationPlugin

xml:: XMLFileConfigurationPlugin

#handler

Page 219: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 219 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<value>Otro valor</value> </entry> </map> </property> <property name="contexts"> <list> <value>CONTEXTO.UNO</value> </list> </property> </bean>

En la propiedad “properties” se deben indicar todos los pares {clave, valor} que va a servir el plugin. Este plugin puede ser actualizado, pero no se pueden guardar los cambios realizados.

• PropertiesFileConfigurationPlugin, que obtiene los parámetros de un fichero de properties.

<bean id="baseConfigurationPlugin" parent="abstract ConfigurationPlugin"> <constructor-arg><value>basePlugin</value></constr uctor-arg> <property name="file"><value>${base.module.file}</ value></property> <property name="priority"><value>1</value></proper ty> </bean>

En la propiedad “file” se debe especificar la ruta del fichero .properties a cargar. Esta ruta puede ser absoluta, relativa al contexto de la aplicación Web, o al classpath (siempre que empiece por la cadena “classpath://”).

11.2.1.2.2. Plugins basados en XML

Este tipo de plugins obtienen la configuración de un documento XML. Este documento puede estar en memoria (en un String, por ejemplo), o en un fichero.

• XMLStringConfigurationProperties. Carga la configuración directamente de un String. <bean id="xmlStringConfigurationPlugin" class="myapp.MyXMLStringConfigurationPlugin"> <constructor-arg><value>xmlStringPlugin</value></c onstructor-arg> <property name="priority"><value>12</value></prope rty> <property name="xml"> <value> <![CDATA[ <elements>

Page 220: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 220 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<element value='myId' label='bar'/> <element value='myId2' label='bar2'/> </elements> ]]> </value> </property> <property name="contexts"> <list> <value>EXAMPLE.CONTEXT</value> </list> </property> </bean>

Para configurar este plugin, debe escribirse el documento XML (que contiene la configuración) en la propiedad “xml”. Es importante observar que debe escribirse en una sección CDATA, de lo contrario, el fichero de inicio no sería valido de acuerdo a su DTD. Este plugin es de solo-lectura.

• XMLFileConfigurationPlugin. Carga la configuración de un fichero XML.

Para configurar este plugin, se debe indicar el fichero XML de configuración en la propiedad “file”. El path de este fichero puede ser absoluto, relativo respecto al contexto de la aplicación Web, o respecto al classpath (si empieza por la cadena “classpath://”, como ocurre en el ejemplo).

Debido a la flexibilidad del formato XML, este tipo de plugins delegan el análisis del documento, y la gestión de los parámetros de configuración, en un objeto auxiliar: XMLConfigContentHandler. Para definir un plugin de configuración XML, es necesario extender la clase XMLConfigContentHandler. Se deben implementar métodos para:

• Analizar el documento XML. El análisis del documento se realiza utilizando el API Apache Commons Digester. Los métodos a implementar son: setDigesterRules(Digester), en el que se definirán las reglas del Digester para analizar el fichero y registerDTDs(Digester), para registrar las DTD que se quieran utilizar para validar el documento XML proporcionado.

• Gestionar los parámetros de configuración. Además, se deben implementar métodos que permitan obtener un determinado parámetro (getParameter()), escribir un valor (setParameter()), etc.

/** * Clase que se encarga de cargar la configuración JAAS del sistema. * Disponible en el core de openFWPA */ public class JAASConfigurationPlugin extends XMLFil eConfigurationPlugin {

Page 221: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 221 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

/** * Logger de la clase. */ protected static final Logger logger = Logger .getLogger(JAASConfigurationPlugin.class); /** * Clase auxiliar para gestionar le contenido del fichero XML de * configuración */ class JAASConfigContentHandler extends XMLConfigCo ntentHandler { /** * Constructor de la clase interna */ public JAASConfigContentHandler(String name) { super(name); setValidate(true); } /** * Declaracion de DTD publica */ protected static final String DTD = "-//Framework PA - Team//DTD JAAS Configuration 1.3F//ES"; /** * Ubicacion en el classloader de la DTD */ protected static final String DTD_FILE = "es/princast/framework/resources/jaas-config.dtd "; protected void registerDTDs(Digester digester) { //Establece la ubicacion de la DTD URL url = Thread.currentThread().getContextClass Loader() .getResource(DTD_FILE); if (url == null) { log.error("No se ha encontrado DTD en la ubicac ión " + DTD_FILE + ". Se producirá un error parseando” + " el documento XML"); } else {

Page 222: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 222 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

digester.register(DTD, url.toString()); if (log.isDebugEnabled()) { log.debug("Utilizando DTD en: " + url.toString()); } } } protected void setDigesterRules(Digester digester ) { digester .addObjectCreate("jaas", "es.princast.framework.facilities.security.jaas.co nfig.ApplicationConfigBean"); digester .addObjectCreate("jaas/application", "es.princast.framework.facilities.security.jaas.co nfig.ConfigBean"); digester.addSetProperties("jaas/application"); digester.addCallMethod("jaas/application/module" , "setModule", 0); digester .addObjectCreate("jaas/application/options/option" , "es.princast.framework.facilities.security.jaas.co nfig.OptionBean"); digester.addCallMethod("jaas/application/options/o ption/name", "setName", 0); digester.addCallMethod("jaas/application/options/o ption/value", "setValue", 0); digester .addSetNext("jaas/application/options/option", "addOption", "es.princast.framework.facilities.security.jaas.co nfig.OptionBean");

Page 223: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 223 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

digester .addSetNext("jaas/application", "addAppConfig" , "es.princast.framework.facilities.security.jaas.co nfig.ConfigBean"); } public void setParameter(String key, String value ) { log.info("Fichero de configuracion JAAS-CONFIG n o soporta " + "actualizacion directa. Si quiere modificar la configuración, debe " + "realizar los cambios directamente sobre el fichero y recargarlo " + "mediante la consola."); } public List getConfigurationObjects() { ArrayList objs = new ArrayList(1); objs.add(getXMLObject()); return objs; } public String getParameter(String key) { if (key == null || !SecurityGlobals.JAAS_CONFIG_OBJECT.equals(key)) { return null; } return getXMLObject().toString(); } public Enumeration getKeys() { Vector keys = new Vector(1); keys.add(SecurityGlobals.JAAS_CONFIG_OBJECT); return keys.elements(); } public Object getConfigurationObject(String key) {

Page 224: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 224 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

return (key != null && SecurityGlobals.JAAS_CONFIG_OBJECT.equals(key)) ? g etXMLObject() : null; } public void setConfigurationObject(String key, Ob ject value) { log.info("Fichero de configuracion JAAS-CONFIG n o soporta " + "actualizacion directa. Si quiere modificar la configuración, debe " + "realizar los cambios directamente sobre el fichero y recargarlo " + "mediante la consola."); } public String getParameter(String path, String ke y) { if (log.isDebugEnabled()) { log.debug("Modulo de configuracion de JAAS-CONF IG no soporta contextos anidados. " + "Se ignora el contexto "+path); } return getParameter(key); } public Object getConfigurationObject(String path, String key) { if (log.isDebugEnabled()) { log.debug("Modulo de configuracion de JAAS-CONF IG no soporta contextos anidados. " + "Se ignora el contexto "+path); } return getConfigurationObject(key); } } /** * Constructor del plugin de configuracion */ public JAASConfigurationPlugin(String name, File f ile) { this(name); setFile(file);

Page 225: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 225 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

} /** * Constructor del plugin de configuracion */ public JAASConfigurationPlugin(String name) { super(name); setHandler(new JAASConfigContentHandler(name)); } }

12. Filtros Web

Con vistas a poder acceder de forma sencilla a las peticiones y respuestas HTTP que circulan entre el navegador del cliente y el servidor Web se proporciona una arquitectura de filtros extensible de forma sencilla.

12.1. Filtros de openFWPA. PrincastFilter

Todos los filtros (Servlet Filters) proporcionados por openFWPA extienden del filtro base: PrincastFilter. Este filtro extiende la jerarquía básica de Servlet Filters proporcionada por la plataforma J2EE y ofrece algunas funcionalidades extra. En caso de que las aplicaciones vayan a implementar sus propios filtros, es recomendable siempre extender la clase PrincastFilter. En openFWPA, los filtros se almacenan en el directorio “web/filter” tal y como podemos ver en la siguiente imagen:

Page 226: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 226 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

70 Path directorio filter en openFWPA

12.1.1. Implementación de un nuevo filtro

El proceso de implementación de un nuevo filtro que haga uso de la infraestructura facilitada por openFWPA es muy sencillo. A continuación se detallan los pasos a seguir:

Page 227: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 227 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• Crear una clase Java que extienda la clase PrincastFilter.

• Sobrescribir el método filter() para añadir la lógica de negocio del filtro.

Atención

El método que se debe sobrescribir es filter() y no doFilter() como se haría para escribir un filtro normal. El método doFilter() es final en la clase PrincastFilter.

• Crear un interfaz java que extienda el interfaz PrincastFilterMBean. Este interfaz debe tener

como nombre el de la clase Java que define el nuevo filtro seguido de MBean. Esto es necesario para poder hacer uso de las facilidades JMX aportadas por openFWPA para la gestión de los filtros. No es necesario que el nuevo interfaz tenga métodos.

• Si se quiere implementar alguna lógica al inicializar el filtro, se debe extender el método

initFilter().

Atención

El método init() de la clase PrincastFilter es final, por lo tanto no se puede extender dicho método.

Ejemplo de filtro disponible en la aplicación de ejemplo de openFWPA “sampleapp”. /** * Filtro Web que se encarga de extraer los principals de autenticación y, * con ellos, crear un objeto UserContainer . */ public class LoginFilter extends PrincastFilter implements LoginFilterMBean{ protected void filter(ServletRequest req, Servl etResponse resp, FilterChain chain) throws IOException, ServletException { if (!(req instanceof HttpServletRequest)) { chain.doFilter(req, resp); return; } HttpServletRequest request = (HttpServletRe quest) req; UserVO user = new UserVO();

Page 228: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 228 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

// Se obtiene el subject Subject subject = (Subject) request.getSess ion(true).getAttribute( SecurityGlobals.SUBJECT); // Cargamos sus credenciales. if (subject == null) { // el usuario todavía no está autentica do chain.doFilter(req, resp); return; } UserContainer existingContainer = UserConta iner .getUserContainer(request); // si ya cargue los datos anteriormente ent onces retorno if (existingContainer.getUserVO() != null) { chain.doFilter(req, resp); return; } UserVOLoader.populateUserVO(user, subject); if (this.logger.isDebugEnabled()) { this.logger.debug("Se ha autentificado al usuario:\n" + user.toXML()); } existingContainer.setUserVO(user); chain.doFilter(req, resp); } } Ejemplo de interfaz para el filtro anterior, sin métodos disponibles. /** * Interface MBean para el filtro LoginFilter . */ public interface LoginFilterMBean extends Registrab leMBean{ //Empty }

Page 229: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 229 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

12.1.2. Gestión de los filtros de forma dinámica

Una de las características más novedosas aportadas por openFWPA en cuanto a la gestión de los filtros es que estos pueden ser conectados y desconectados “en caliente” utilizando para ello una consola JMX. De esta forma, el administrador de la aplicación, en base a determinadas métricas de rendimiento, puede decidir en un momento dado si desea tener un filtro que comprima la respuesta enviada al cliente, arrancándolo o apagándolo sin necesidad de tener que para la aplicación para aplicar la nueva configuración en el fichero web.xml.

12.1.3. Filtros activables por reglas

Los filtros que extienden PrincastFilter pueden ser desactivados para un conjunto determinado de URLs. Este tipo de filtros se pueden mapear sobre un patrón de URL (como cualquier otro filtro) pero es posible definir un subconjunto de patrones de URL, para las cuales el filtro no entrará en acción. Cada uno de los patrones de URL excluidos de la acción del filtro se definirá utilizando un “init

param”, en el fichero web.xml. Estos parámetros deben cumplir el siguiente convenio de nombrado: “EXCLUDED.URL.<Identificador descriptivo del patrón>”. <filter> <filter-name>ExampleByRuleFilter</filter-name> <filter-class> es.princast.example.web.filter.ExampleFilter </filter-class> <init-param> <param-name>EXCLUDED.URL.SELECCION</param-name> <param-value> /action/seleccionaExplotacion </param-value> </init-param> <init-param> <param-name>EXCLUDED.URL.LOGOUT</param-name> <param-value> /action/logout </param-value> </init-param> </filter> Además, utilizando la consola JMX, es posible actualizar, “en caliente”, los patrones de URLs que se excluirán del efecto del filtro.

Page 230: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 230 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

12.2. Configuración del filtro SecurityFilter

Para el control de acceso de las aplicaciones que usen openFWPA se facilita un filtro al efecto. Para poder hacer uso de este filtro es necesario definirlo en el fichero de configuración web.xml. Un ejemplo de la configuración a añadir en este fichero se presenta a continuación: <filter> <filter-name>SecurityFilter</filter-name> <filter-class> es.princast.framework.web.filter.security.cor p.PrincastSecurityFilter

</filter-class> </filter> ... <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> El filtro de seguridad se enmarca dentro del sistema de seguridad de openFWPA. Para más información, puede revisar el apartado “15. Seguridad”, de este mismo documento.

12.3. Filtro de navegación

El Filtro de Navegación (clase NavigationFilter) tiene dos objetivos:

• Mantener siempre el conocimiento de las entradas de menú (y submenú) activas, evitando la necesidad de utilizar tecnologías del lado del cliente como JavaScript y Cookies.

• Mantener el estado de la barra de navegación (Ver Sección 9.9.2, “Barra de navegación.”).

<filter> <filter-name>NavigationFilter</filter-name> <filter-class> es.princast.framework.web.filter.navigation.Navig ationFilter </filter-class> </filter> ...

Page 231: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 231 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<filter-mapping> <filter-name>NavigationFilter</filter-name> <url-pattern>/action/*</url-pattern> </filter-mapping> El Filtro de Navegación debe estar mapeado a todas las URLs referenciadas por alguna entrada de menú o submenú. El Filtro de Navegación, extrae de la Request los valores de los parámetros GET que indican la entrada de menú y submenú activas y, a partir de ellas, se encarga de mantener el estado del menú y de la barra de navegación, manteniéndolos siempre sincronizados. Para conocer los nombres de los parámetros GET a los que tiene que acceder, el Filtro de Navegación implementa el interface Configurable (es decir, es un objeto configurable por el sistema de configuración de openFWPA) que escucha el contexto del menú (MENU.CONTEXT), lo que significa, que no se requiere ninguna configuración especial para el Filtro de Navegación, siempre y cuando, se configure convenientemente el menú.

12.4. Filtros de Activación

En ocasiones, es necesario poder activar (o desactivar) una aplicación o determinadas partes de la misma, de forma declarativa. OpenFWPA incluye una clase base (ActivacionFilter) que facilita la implementación de filtros Web para la gestión de la activación de las aplicaciones. Básicamente este tipo de filtros tienen dos responsabilidades:

• Determinar cuando la aplicación está activa (o no).

• En caso de que la aplicación esté inactiva ejecutar alguna operación (generalmente redireccionar a una página de aviso).

Para implementar filtros de activación es necesario extender la clase ActivationFilter. Los métodos más relevantes de esta clase son:

• isActive(). Determina cuando el recurso solicitado (URL) está activo. Este método devolverá true si el recurso está activo. Se trata de un método abstracto y, por tanto, es de implementación obligatoria por parte de las subclases.

Page 232: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 232 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• handleInactive(). Realiza la lógica correspondiente en caso de que el recurso solicitado por el cliente no esté activo. La implementación por defecto redireccionará a una página previamente configurada.

• configure(). Los filtros de activación pueden ser configurados mediante el Sistema de

Configuración de openFWPA. Por defecto, todos los filtros de activación toman parámetros del contexto "ACTIVATION.FILTER". Es posible cambiar el nombre del contexto utilizando el parámetro de inicialización del filtro (init-param en web.xml) de nombre: "CONTEXT". Dentro de este contexto, se puede definir una página de redirección (en caso de que el recurso no esté activo), utilizando el parámetro "ERROR.URL".

12.4.1. Filtro de Temporalidad

El Filtro de Temporalidad permite activar/desactivar una aplicación (o partes de la misma) en función de la fecha en la que se produzca el acceso. El Filtro de Temporalidad (clase TimingFilter) es un filtro de activación y, por tanto, tiene todas sus características. El Filtro de Temporalidad permite que los recursos que protege estén activos únicamente durante determinados intervalos temporales, definidos como parámetros de configuración. Estos parámetros seguirán el siguiente convenio de nombrado: ACTIVE.INTERVAL.<id del intervalo>. El valor del intervalo, se especificará siguiendo el convenio: <inicio intervalo> - <fin intervalo>, pudiendo especificarse el inicio o el fin del intervalo de las siguientes formas:

• Con una fecha, especificada según cualquier formato estándar válido (SimpleDateFormat). El formato concreto a utilizar se define con el parámetro de configuración: DATE.FORMAT. Por defecto vale: "dd/MM/yyyy HH:mm:ss".

• Utilizando el carácter "?". En este caso, se supone que se trata de un intervalo abierto, cuyo

extremo no está especificado. Algunos ejemplos de intervalos pueden ser: ACTIVE.INTERVAL.1 = 22/01/2012 11:11:11 - 22/02/201 2 11:11:11 ACTIVE.INTERVAL.2 = 22/04/2012 11:11:11 - ? ACTIVE.INTERVAL.3 = ? - 22/01/2106 11:11:15 ACTIVE.INTERVAL.4 = ? - ?

Page 233: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 233 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

13. Excepciones

OpenFWPA dispone de su propia jerarquía de excepciones. La política general de manejo de excepciones en openFWPA es que se utilicen excepciones Runtime (no manejadas estáticamente).

71 jerarquía de excepciones

Page 234: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 234 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La clase base para la creación de excepciones es PrincastException. Existen dos ramas en esta jerarquía de excepciones runtime:

• Excepciones de sistema (PrincastSystemException), reservadas para openFWPA y sus componentes.

• Excepciones de modelo (PrincastModelException), que son disparadas por las excepciones.

Como norma general, las aplicaciones no deberían nunca extender las excepciones del sistema. Siempre deben extender PrincastModelException. Además, openFWPA también tiene una clase base para la creación de excepciones gestionadas: PrincastRequiredHandlingException. La excepción DeprecatedAPIException se reserva para ser disparada desde métodos deprecados en los que no sea posible implementar una lógica alternativa.

13.1. Loggeo de las Excepciones en los DAO

A pesar de que no hace falta capturar las excepciones producidas en el acceso a datos, es recomendable imprimir en el log de la aplicación, la excepción que se produce. Para ello, basta con definir dos spring beans en el fichero dao-beans.xml, y las excepciones que se produzca quedan loggeadas automáticamente. <!-- Con estas dos definiciones se auditan todas la s excepciones que se produzcan en los DAOs a nivel de log de ERROR--> <bean id="loggerThrowsAdvice" class="es.princast.framework.facilities.interceptor .logger.LoggerThrowsAdvice"> <property name="level"><value>ERROR</value></prope rty> </bean> <bean id="daoBeanAutoProxy" class="org.springframework.aop.framework.autoproxy. BeanNameAutoProxyCreator"> <property name="beanNames"><value>*DAO</value></pr operty> <property name="interceptorNames"> <list> <value>loggerThrowsAdvice</value> </list> </property>

Page 235: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 235 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

</bean> La primera definición de bean loggerThrowsAdvice, indica la clase de log que se va a usar. La propiedad más importante es el nivel de log, en el ejemplo se indica que las excepciones se van a loggear a un nivel de ERROR (son válidos los mismos niveles de log que para log4j). La segunda definición indica los beans a los que se va a aplicar el log, se aplican por nombre de bean. En este caso se indica con un patrón "*DAO", esto quiere decir que el log se aplica a todos los métodos de todos los beans que su identificador acabe en la cadena DAO. Aunque aquí se auditen los DAO, se puede auditar cualquier otra clase por su definición de bean de Spring, por ejemplo todos los "Delegate" con el patrón "*Delegate".

13.2. Excepciones durante el proceso de autenticación

En caso de que durante el proceso de autenticación se lance alguna excepción, ésta es almacenada en la sesión del usuario bajo la clave LOGIN_EXCEPTION, que se puede encontrar en la clase SecurityGlobals. Pudiera darse el caso de querer mostrar un determinado mensaje de error en la capa de presentación en función de la excepción que se haya producido. Para ello se proporciona un tag JSP denominada <instanceOf> y que recibe los siguientes parámetros:

• variableName. Nombre de la clave bajo la cual se busca la excepción.

• className. Nombre cualificado de la excepción con la que se realiza la comprobación. Un ejemplo de uso de esta etiqueta se presenta a continuación: <princast:instanceOf variableName="<%=SecurityGloba ls.LOGIN_EXCEPTION%>" className="es.princast.framework.facilities.securit y.exceptions.WrongPasswordException">

<div id="errores"> <ul> <li>

Validaci&oacute;n incorrecta de NIF/NIE y Clave personal </li>

</ul> </div>

</princast:instanceOf>

Page 236: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 236 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Como se puede apreciar se comprueba que la excepción que se encuentra almacenada en la clave SecurityGlobals.LOGIN_EXCEPTION sea de la misma clase que es.princast.framework.facilities.security.exceptions.WrongPasswordException. En caso afirmativo se incluyen los elementos contenidos entre <princast:instanceOf></princast:instanceOf>. Las excepciones que se pueden disparar durante el proceso de autenticación, se encuentran en el core de openFWPA en el paquete: es.princast.framework.facilities.security.exceptions.

Page 237: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 237 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

72 Path del paquete de excepciones para el proceso de autenticación

Page 238: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 238 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

14. Informes

La generación de informes se basa en el proyecto JasperReports (http://jasperforge.org/projects/jasperreports) JasperReports es una librería de clases que puede verse como un motor de reporting para desarrollos java. El principal objetivo de este proyecto es facilitar la construcción de documentos con contenido dinámico y su visualización en diferentes formatos. JasperReports organiza la información que le servirá para generar los documentos en forma de fichero XML. El fichero XML, de acuerdo al DTD, es visto como el diseño del informe. Una vez en disposición de un diseño XML válido, es necesario realizar un proceso de compilación, que generará un objeto que es serializado, y podría ser almacenado en disco con extensión .jasper. La compilación validará todas las expresiones java que pudieran estar embebidas en el XML. Una vez compilado, y para proveer al informe con datos dinámicos, se realiza el proceso de completado (fill). Este proceso puede recibir diferentes fuentes de datos, entre ellas conexiones a bases de datos relacionales (instancias de clase Connection), colecciones o arrays de Beans (instancias de clase JRDataSource de la librería de JasperReports) o fuentes de datos personalizadas, extendiendo el interface JRDataSource. Otra forma de pasar información dinámica a los documentos es a través de parámetros de informe, que forman parte del diseño XML y pueden ser establecidos por programación, e incluso tener valores por defecto en diseño. Posibilita la salida de informes a pantalla, impresora o a fichero en diversos formatos (PDF, HTML, CSV, XML).

73 Vision general (jasperReports)

Page 239: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 239 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

14.1. Creación de diseños XML

El proyecto JasperReports no provee de ninguna herramienta adicional que facilite la labor de la creación de los ficheros XML. En este punto, un desarrollador que pretenda crear el diseño XML de un documento necesario para su aplicación, debería crearse el fichero XML desde un editor de texto, o editor XML. Evidentemente, esto es una tarea tediosa y poco operativa. Más bien se necesitaría otra herramienta que facilitara la labor de visualizar, compilar y generar el XML del documento que se está diseñando, una herramienta visual del tipo WYSIWYG. Existen varias herramientas de este tipo desarrolladas como proyectos abiertos. El desarrollador es libre de elegir su herramienta preferida; el openFWPA no provee de ninguna de ellas, aunque se han realizado las pruebas con el proyecto iReport-Designer for JasperReports (http://jasperforge.org/projects/ireport)

Page 240: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 240 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

74 iReport

14.2. La herramienta iReports

La herramienta iReports es un editor visual de ficheros XML listos para ser usados por el motor de reporting JasperReports. Trabaja en modo standalone (aplicación de ventana de java) y tiene un interfaz claro. En la página del proyecto http://jasperforge.org/projects/ireport puede obtenerse una amplia documentación sobre como manejar esta herramienta, e incluso un video tutorial que muestra algunos de los aspectos más interesantes sobre ella.

Page 241: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 241 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Al estar estrechamente relacionada con JasperReports, es necesario conocer los aspectos en que este último organiza su información (bandas, grupos, subreports, parameters, fields, variables…) para optimizar el manejo de la herramienta visual.

14.2.1. Visión general de la Interfaz

75 iReport (Visión general de la interfaz)

14.2.2. Compilar y establecer programas externos

Una vez instalado el iReport, lo primero que habría que hacer es establecer los programas externos que se utilizarán. Para ello hay que ir a la opicón de Menú � Opciones � Opciones � Pestaña programas externos.

Page 242: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 242 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

En la pestaña Compilador podremos establecer el directorio de compilación por defecto (donde nos generará los ficheros .jasper asociados a los reports). Los .jasper asociados a los reports en OpenFWPA tienen que estar en la carpeta del proyecto WEB-INF/reports, por lo tanto, se le puede establecer esta carpeta como directorio de compilación.

Page 243: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 243 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Otra forma de compilar los ficheros xml asociados a los informes es ejecutar la tarea de ant: “compile.report”, que está en el fichero build.xml de la carpeta src/main/java/buid.xml.

Page 244: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 244 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

14.2.3. Nuevo informe con iReports

Opción de menú Fichero � Nuevo documento Aquí deberá definirse el nombre del reporte, tamaño de la pantalla, orientación, márgenes, etc.

76 Propiedades del informe

La apariencia del layout (plantilla) de la página del informe es la siguiente:

Page 245: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 245 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

77 Layaout de la página del informe

Donde:

• title: Aparece sólo al inicio del reporte. El título se escribe en está sección. Ejemplo: “Reporte de Desempeño de los empleados”

• pageHeader: Aparece en la parte superior de cada página. Puede contener información como la fecha y hora, nombre de la organización, etc.

• columnHeader: Sirve para listar los nombres de los campos que se van a presentar (desplegar). Por ejemplo: “Nombre del Empleado”, “Hora de Entrada”, “Hora de Salida”, “Horas trabajadas”, “Fecha”, etc.

• Detail: En esta sección se despliegan los valores correspondientes a las entradas de campos definidas en la sección anterior. Por ejemplo “Juan Perez”, “09:00”, “18:00”, “9”,”2005-04-27”.

• columnFooter: Puede presentar información sumarizada para cada uno de los campos. Por ejemplo “Total de Horas Trabajadas: 180”

• pageFooter: Aparece en la parte inferior de cada página. Este parte puede presentar, el contador de páginas como “Página 1/7”

Page 246: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 246 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• summary: Esta sección se usa para proporcionar información sumarizada de los campos presentes en la sección “detail” por ejemplo para el caso de las horas trabajadas de cada empleado se puede definir un objeto gráfico tipo “pie” para tener una mejor comparación y comprensión visual de los datos.

Los objetos de texto, imágenes,…, pueden ser colocados en la plantilla del documento usando el método de arrastrar y pegar. Para insertar texto puro usar:

Para insertar campos (Fields) usar:

14.2.4. Parametros en iReport

Opción de Menú � Ver � Parámetros. Los parámetros son una buena forma de añadir datos dinámicos al informe y parametrizar éste, de forma que se puedan visualizar elementos según el valor o rango de algún parámetro, e incluso modificar la consulta SQL según parámetros. Los parámetros añaden más flexibilidad a la generación de los informes, hasta el punto de que es posible crear informes sin fuente de datos, y que toda su información llegue por parámetros. Un parámetro tiene un nombre, un tipo (clase java seleccionable de una lista) y opcionalmente un valor por defecto (expresión java que será compilada en el proceso de compilación y evaluada en el proceso de completado del informe) Los parámetros son referencias a objetos que son pasadas al proceso de completado (fill) del informe. Su uso, como ya se ha comentado, servirá para enviar información al motor de reporting que no puede ser encontrada en la fuente de datos (DataSource). Los parámetros se identifican en el fichero XML por construcciones similares a la siguiente:

<parameter name="ejemplar_para" isForPrompting="false" class="java.lang.String"> <defaultValueExpression > <![CDATA[new String("Ejemplar para ... por defecto")]]> </defaultValueExpression> </parameter>

Page 247: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 247 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

En el entorno de iReports, se puede hacer referencia a este parámetro mediante la construcción $P{ejemplar_para}

78 iReport - Declaración de parámetros

14.2.5. Fields

Los fields representan la forma de mapear campos en el diseño del report con datos de la fuente de datos. Si el DataSource es una base de datos, entonces el mapeo es directo con los nombres de campos en una o varias tablas. Si el DataSource es una collección de Beans, el mapeo se realizará con las property´s de éstos. Un Field se puede idetificar en el XML por una construcción como:

<field name="DL_FINALIDAD" class="java.lang.String"/> En el entorno de iReports se le puede hace referencia como $F{DL_FINALIDAD}

14.2.6. Variables

Se declaran como expresiones en java, y más tarde pueden ser usadas de forma masiva. Pueden servir como forma de no repetir código. Tambíen se utilizan para realizar cálculos. Exiten funciones built-in que facilitian algunas tareas de cálculo, como Count, Sum, Average, Lowest, Highest y StandardDeviation. Las variables serán reinicializadas según la jerarquía de niveles: Report, Page, Column y Group. Exiten una serie de variables inherentes a todo informe (built-in variables), a las que se puede hacer referencia en todo momento:

Page 248: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 248 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• PAGE_NUMBER • REPORT_COUNT • COLUMN_COUNT

En el entorno de iReports se les puede hace referencia como $V{NOMBRE_DE_VARIABLE}

14.3. Clases del OpenFWPA para la renderización de informes

En openFWPA se han incluido dos clases para la generación de informes: PrincastReport y PrincastMultiReport. La primera permite generar informes simples y la segunda de ellas, crear multi-reports a partir de la agregación de varios informes sencillos.

79 API informes openFWPA

14.3.1. Informes simples

Para crear un informe simple se usará la clase PrincastReport. Para poder crear un PrincastReport, es necesario indicarle, en su constructor, los parámetros:

• Nombre del informe: El informe debe tener un nombre. Este nombre puede ser el que se utilice para generar un fichero PDF.

• Fuente de datos: El origen de datos para cargar el informe también debe ser especificado. Por defecto, se utilizará el origen de datos nulo: JREmptyDataSource. El informe no tomará datos de ninguna fuente.

• Report compilado: Se debe suministrar un stream de entrada (InputStream) que permita leer la definición compilada del informe. Este stream debe estar abierto sobre un fichero .jasper.

Page 249: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 249 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Además, si en el diseño del informe se han definido parámetros, sus valores deben ser especificados al PrincastReport utilizando el método setParams(Map).

Antes de obtener el informe es MUY recomendable pregenerarlo (para validar que no se producen errores antes de exportar el informe). Para pregenerar un informe se debe utilizar el método process(). Para obtener un informe de un PrincastReport (correctamente creado y con los parámetros que necesite asignados) se puede utilizar uno de los siguientes métodos:

• getReportToPrint(). Devuelve el objeto jasper imprimible: JasperPrint. Este objeto puede ser manejado por las clases de Jasper Reports (se puede exportar a múltiples formatos, imprimir, etc.)

• getPDFContent(). Devuelve el informe exportado a formato PDF, en un array de bytes, listo para ser volcado a un fichero (o enviado a un cliente, etc.)

• exportPDF(OutputStream). Exporta el informe, en formato PDF, al OutputStream que se pasa como parámetro.

A continuación se muestra un ejemplo de construcción de un PrincastReport. //Obtener el fichero del Report (.jasper) InputStream stream = loadReport(REPORT_NAME+".jaspe r"); //Obtener origen de datos List listaProducto = CarritoDelegateFactory.getCarritoDelegate().getList aProducto(); JRDataSource dataSource = new JRBeanCollectionDataS ource(listaProducto); //Obtener parametros Map parameters = new HashMap(); MessageResources messages = (MessageResources) request.getAttribute(Globals.MESSAGES_KEY); parameters.put("P_Titulo", messages.getMessage("rep ort.title")); parameters.put("P_AmpliacionTitulo", messages.getMessage("report.description")); //Crear report PrincastReport report = new PrincastReport(REPORT_N AME, dataSource, stream); report.setParams(parameters); report.process();

Page 250: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 250 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

14.3.2. Multi Reports

Los Multi-reports son informes compuestos de informes simples. El objetivo de los multireports es agrupar un conjunto de informes para que puedan ser volcados en un mismo fichero PDF. El openFWPA incluye la clase PrincastMultiReport para la generación de informes compuestos. Esta clase es muy simple de manejar: basta con especificarle un nombre (para el fichero PDF) y añadir todos los informes simples que se quieran adjuntar con el método addReport(PrincastReport report). Los multi-reports también deben ser procesados, al igual que los informes simples, utilizando el método process(). El informe se puede obtener con el método getPDFContent() que, al igual que en la clase PrincastReport, devuelve un array de bytes con el informe en formato PDF, listo para ser volcado a un fichero. También se puede exportar con el método exportPDF(OutputStream).

14.3.2.1. Forma de actuar:

• Crear un objeto PrincastMultiReport • Crear todos los reports simples que se necesiten • Añadirlos con addReport

14.3.3. Las fuentes de datos de los informes.

Los informes visualizarán contenido dinámico, provenientes de dos tipos diferentes de fuentes de datos:

• DataSources JDBC Connection: conexión con una base de datos relacional. • JRDataSources: fuentes de datos JasperReports. La librería de clases de Jasper Reports provee

de una serie de implementaciones de este tipo de fuentes de datos. Las más interesantes son aquellas que gestionan collecciones de Beans java (en forma de Collection, Array o Map de Beans). Es recomendable el uso de estas fuentes de datos, en detrimento de las anteriores, ya que de esta forma no se rompe la encapsulación de las capas de la aplicación.

14.3.4. Utilizando JasperReports en Linux / Unix sin X11.

ADVERTENCIA: No es posible generar informes con imágenes (escudos, marcas de agua, códigos de barras, etc.) en un entorno Unix/Linux sin las librerías X11.

14.3.5. Clase para la generación de tablas en PDF.

El FW-PA incluye la clase PDFTableExporter para la generación de informes PDF en forma de tabla, de esta manera es posible realizar de una manera sencilla listados en PDF. Para usar esta clase se hará

Page 251: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 251 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

en combinación con una PrincastPDFReportAction, sobrescribiendo el método getReport(). Un ejemplo de su uso es el siguiente: // número de columnas de la tabla, las filas se aju sta automáticamente int columnas = 3; // nombre del report String REPORT_NAME = "tabla"; PDFTableExporter tableExporter = new PDFTableExport er(REPORT_NAME, columnas); // se establece el título del report tableExporter.setTitle("Mi título"); // se añaden celdas de cabecera (aparecen sombreada s) tableExporter.addCellHeader("Enero"); tableExporter.addCellHeader("Febrero"); tableExporter.addCellHeader("Marzo"); // se añaden las celdas de la tabla tableExporter.addCell("1"); tableExporter.addCell("2"); tableExporter.addCell("3"); // se retorna el objeto return tableExporter;

14.4. Ejemplo de creación de infome con openFWPA

En los próximos apartados mostraremos como se diseña un informe con openFWPA. Este informe se encuentra en la aplicación de ejemplo (sampleapp) que se distribuye con openFWPA.

14.4.1. Diseñar con iReports y obtener XML

Declaramos los Fields (campos del informe) que vamos a utilizar: opción de Menú Ver � Campos del informe.

Page 252: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 252 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

80 campos del informe

Declaramos los parámetros que vamos a utilizar: opción de Menú Ver � Parámetros del informe.

Declaramos las variables que vamos a utilizar: opción de Menú Ver � Variables del informe.

Page 253: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 253 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Conformamos el informe con todas las imágines, campos de texto, field, parámetros, …

Page 254: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 254 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

81 Página del informe

14.4.2. Guardar el XML

Copiamos o guardamos el xml asociado a la página del informe en la carpeta src/main/jasperreports:

Page 255: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 255 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

82 Ubicación de ficheros XML

14.4.3. Compilación

Una vez compilado el informe anterior obtenemos el fichero .jasper que tiene que estar ubicado en la carpeta src/main/webapp/WEB-INF/reports.

Page 256: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 256 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

83 Ubicación de ficheros .jasper

Para compilar el informe podemos configurar el iReport para que compile directamente en esa ruta o ejecutar la tarea de Ant “compile.reports.”

14.4.4. Crear clase Action que extienda PrincastPDFReportAction (abstracta)

Las clases Actions asociadas a los informes se encuentran ubicadas en:

Page 257: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 257 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación mostramos el código fuente de la clase ProductosPDFReportAction donde sobrescribimos el método getReport() para obtener un PDFProvider: import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.data.JRBeanColle ctionDataSource; import org.apache.struts.Globals; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.util.MessageResources; import es.princast.framework.core.exceptions.Princa stModelException; import es.princast.framework.facilities.providers.P DFProvider; import es.princast.framework.facilities.reports.Pri ncastReport; import es.princast.framework.web.action.report.Prin castPDFReportAction; import es.princast.sampleapp.web.delegate.CarritoDe legate;

Page 258: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 258 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

/** * Action para generar un informe PDF con la lista de productos */ public class ProductosPDFReportAction extends Princ astPDFReportAction { // inyeccion de dependencia (WEB-INF/beans/web/act ion-defs.xml) /** * El delegate que permite obtener la lista de pro ductos */ protected CarritoDelegate carritoDelegate; /** * Asigna el delegate que permite obtener la lista de productos * * @param carritoDelegate el delegate que gestiona el carrito */ public void setCarritoDelegate(CarritoDelegate carritoDelegate) { this.carritoDelegate = carritoDelegate; } /** * El nombre del informe a generar */ private final static String REPORT_NAME = "product osReport3"; protected void catchException(Exception e, ActionM apping arg1, ActionForm arg2, HttpServletRequest arg3, HttpServletResponse arg4) { //En este método habrÃ-a que tratar la excepció n. //Por ejemplo, redireccionar a pagina de error. throw new PrincastModelException(e, "Al ejecutar lógica", ""); } protected PDFProvider getReport(HttpServletRequest request,

HttpServletResponse response, ActionForm form, Acti onMapping mapping) {

//Obtener el fichero del Report (.jasper) InputStream stream = loadReport(REPORT_NAME+".jas per"); //Obtener origen de datos

Page 259: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 259 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

List listaProducto = carritoDelegate.getListaProd uctoPDF(); JRDataSource dataSource = new JRBeanCollectionDataSource(listaProducto); //Obtener parametros Map parameters = new HashMap(); MessageResources messages = (MessageResources) request.getAttribute(Globals.M ESSAGES_KEY); parameters.put("P_Titulo", messages.getMessage("r eport.title")); parameters.put("P_AmpliacionTitulo", messages.getMessage("report.description")); //Crear report PrincastReport report = new PrincastReport(REPORT_NAME, dataSource, strea m); report.setParams(parameters); report.process(); return report; } }

14.4.5. Resultado final

De la aplicación de ejemplo (sampleapp) podemos generar el informe que hemos construido desde:

Page 260: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 260 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

84 Listado de productos

Page 261: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 261 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

85 Ejemplo de informe

15. Seguridad en aplicaciones con openFWPA

15.1. Seguridad

En el apartado Seguridad se contemplan todas las políticas y herramientas que permiten, tanto controlar (y monitorizar) el acceso a determinadas partes de una aplicación, como aquellas que permiten garantizar la integridad y confidencialidad de los datos que se transmiten. Los conceptos más importantes dentro del control de acceso a una aplicación son la Autentificación y la Autorización.

Page 262: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 262 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La Autentificación es el proceso mediante el cual los privilegios de acceso de un usuario son comprobados antes de que pueda tener acceso a un área protegida de la aplicación. Dentro de la autentificación se pueden distinguir diferentes alternativas, siendo las más recurridas la básica (Basic

authentication) y la basada en formulario (Form-based authentication).

15.1.1. Autentificación básica

La autentificación básica delega el control de acceso al servidor Web. El usuario podrá navegar libremente por el sitio Web sin necesidad de facilitar una contraseña. Sin embargo, cuando se intente acceder a una página protegida será el propio navegador el que solicite al usuario un nombre de usuario (username) y una contraseña (password) mostrándole una ventana de diálogo. Tanto el nombre de usuario como la contraseña son enviados sin encriptar al servidor Web, quien se encarga de validarlos contra un fichero plano, un base de datos o servidor de directorios. Si el usuario consigue validarse se comprueba que se tenga privilegio suficiente para acceder al recurso basándose en ciertas políticas definidas, por ejemplo, en un fichero tipo http.conf. Si la comprobación es positiva se sirve la página al cliente. En caso contrario, se le solicita de nuevo la combinación usuario/contraseña o se le muestra una página de error denegando el acceso.

15.1.2. Autentificación basada en formulario

Suele ser la alternativa más usada por los sitios Web dada su sencillez. Al igual que en la autentificación básica, el usuario puede navegar libremente por los recursos desprotegidos. En el momento que se intenta acceder a un área protegida se redirecciona al usuario a una página de login con un formulario con los campos nombre de usuario y contraseña. Esta autenticación está implementada como un filtro de URLs y se integra con las APIs Java de Seguridad (JAAS).

15.1.3. Autentificación basada en el Filtro de Seguridad de openFWPA

La autentificación basada en el Filtro de Seguridad, es la opción estándar propuesta por openFWPA para el control de acceso. Este tipo de autenticación se basa en un Servlet Filter que se encarga de gestionar tanto el control de acceso como los protocolos de seguridad http/https) a utilizar.

Page 263: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 263 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

86 Esquema del sistema de autenticación

Como resultado del proceso de autenticación y autorización, el Filtro de Seguridad de openFWP, pone a disposición de las aplicaciones todos los datos obtenidos en dicho proceso. Para utilizar la autenticación de openFW-PA, se tendrán que tener en cuenta los siguientes puntos:

• Configuración del Contenedor. El contenedor debe estar configurado convenientemente para permitir el acceso a las aplicaciones bajo el protocolo HTTPS y utilizando sockets SSL-3 (https

con certificado digital).

Page 264: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 264 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• Uso de la seguridad Web J2ee estándar. En la clase HttpServletRequest, se puede interrogar

por las credenciales del usuario para realizar la autenticación.

• Configuración. Es necesario definir los plugins de configuración adecuados.

• Paso de credenciales. Usando una extensión de la clase Principal, donde se proporcionan a la aplicación todos los parámetros que se recogieron durante el proceso de autenticación.

• Diseño de páginas de login. Las aplicaciones necesitan mostrar a los usuarios páginas que les

permitan introducir todos los datos necesarios para su autentificación. Estas páginas deben tener unas características determinadas para poder integrarse con la seguridad de openFWPA.

15.1.3.1. Integración con seguridad Web J2EE

En la clase javax.servlet.http.HttpServletRequest hay tres métodos para controlar el acceso a recursos de la aplicación. Los siguientes párrafos se han extraído de la documentación de la versión 1.3 (JDK 1.3):

• java.lang.String getRemoteUser(). Returns the login of the user making this request, if the user has been authenticated or null if the user has not been authenticated.

• java.security.Principal getUserPrincipal(). Returns a java.security.Principal object containing

the name of the current authenticated user.

• boolean isUserInRole(java.lang.String role). Returns a Boolean indicating whether the authenticated user is included in the specified logical "role".

El método getRemoteUser devuelve el nombre del usuario que realiza la httpRequest. Es equivalente a (PrincastIdentifier)getUserPrincipal()).getId()(ver abajo). El método getUserPrincipal devuelve el Principal más importante (DNI) – en este aso, como una instancia de la clase PrincastIdentifier. Soporta el método getName() definido en Principal) y getId() (definido en PrincastIdentifier). getName() devuelve la cadena “DNI” y getId() devuelve el DNI del usuario. Para la gestión de roles (isUserInRole()) se emplean los roles asignados en el esquema e empleado público. Los roles son tanto para ciudadanos como para empleados públicos.

Page 265: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 265 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

15.1.3.2. Configuración

El sistema de seguridad estándar se configura utilizando el Sistema de Configuración de openFWPA. Todo el sistema tomará parámetros del contexto de seguridad llamado “SECURITY”, por lo tanto, es importante recordar que cualquier plugin que sirve parámetros al sistema de seguridad debe registrarse para el contexto “SECURITY”.

15.1.3.2.1. Parámetros básicos

Los parámetros básicos son:

• app-config. Bajo este parámetro debe indicarse el nombre de la aplicación. Este es el nombre de la configuración JAAS que se utilizará para realizar la autenticación.

• http.PORT. Puerto http que se utiliza para acceder a la aplicación. Si no se especifica este

parámetro, se utilizará el puerto por defecto (80).

• https.PORT. Puerto https que se utiliza para acceder a la aplicación. Si no se especifica este parámetro se utilizará el puerto SSL (443) por defecto.

• https/cert.PORT. Puerto https (SSL-3) con certificado digital de cliente, que se utiliza para

acceder a la aplicación. Si no se especifica este parámetro se utilizará el puerto SSL (443) por defecto.

• http.IP. Dirección IP (o nombre DNS) del servidor que atiende peticiones http. Si no se

especifica este parámetro, la redirección se realizará sobre la IP del propio contenedor.

• https.IP. Dirección IP (o nombre DNS) del servidor que atiende peticiones https (SSL v2), con certificado de servidor. Si no se especifica este parámetro, la redirección se realizará sobre la IP del propio contenedor.

• https/cert.IP. Dirección IP (o nombre DNS) del servidor que atiende peticiones https (SSL v3),

con certificado de cliente. Si no se especifica este parámetro, la redirección se realizará sobre la IP del propio contenedor.

Por ejemplo: <bean id="baseConfigurationPlugin" class="es.princast.framework.core.configuration.plu gins.PropertiesFileConfigurationPlugin"> <constructor-arg><value>basePlugin</value></constr uctor-arg>

Page 266: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 266 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<property name="file"><value>ejemplo.properties</v alue></property> <property name="contexts"> <list> <value>SECURITY</value> <value>ROOT.CONTEXT</value> <value>ACTION.CONTEXT</value> <value>JMX.CONTEXT</value> </list> </property> </bean> Siendo el contenido del fichero carrito.properties, el que sigue: # #Fri Jan 07 10:08:36 CET 2005 CARRITO.AGENCIA=Manin Directo. app-config=Carrito DEFAULT.MENU=MenuMiPerfil ITEM.SEPARATOR = &gt; JMX.SERVER.NAME = SampleApp #PERFORMANCE.TEST.MODE = ON URL_LOGOUT=/carrito #Configuracion de cache CACHE_CONF=classpath:/ehcache.xml #Tamaño de página para displayTag PAGE_SIZE=10 Y el contenido del fichero global.properties, el que sigue: # #Fri Jan 07 10:08:36 CET 2005 HIT.COUNTER=es.princast.framework.core.management.m counters.historic.HistoricalCounter ACTION_MGMT=es.princast.framework.web.action.monito ring.PrincastActionMgmtInterfaceImpl LOGGING_XMLCONF=WEB-INF/log4j.xml http.PORT=8082 https.PORT=8447 https/cert.PORT=8447 ITEM.SEPARATOR = /

Page 267: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 267 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

#JMX.SERVER.ADAPTOR = es.princast.framework.core.management.adapters.JMXR IMBeanServerAdapter JMX.SERVER.ADAPTOR = es.princast.framework.core.management.adapters.OC4J MBeanServerAdapter Ambos ficheros (carrito.properties y global.properties) se encuentran en el directorio WEB-INF de la aplicación de ejemplo “sampleapp”.

87 Path de los ficheros carrito.properties y global.properties

Page 268: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 268 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

15.1.3.2.2. Configuración JAAS

El sistema de autenticación de openFWPA está basada en el estándar JAAS (Java Authentication and

Authorization Service). En realidad, el Filtro de Seguridad, no realiza ninguna tarea de autenticación. Estas funciones son delegadas en un Módulo de Login JAAS (LoginModule). La configuración del módulo a utilizar para autenticar y autorizar usuarios se realiza a través del plug-in de configuración JAAS

(JAASConfigurationPlugin), que debe ser declarado en el fichero de inicialización princast-init-

script.xml. Por ejemplo: <bean id="jaasConfigPlugin" class="es.princast.framework.facilities.security.ja as.config.JAASConfigurationPlugin"> <constructor-arg><value>jaas-config</value></const ructor-arg> <property name="file"><value>WEB-INF/jaas-config.xml</value></property> <property name="contexts"> <list> <value>SECURITY</value> </list> </property> </bean> Los módulos JAAS se configuran, en el openFWPA, mediante el fichero jaas-config.xml, disponible en el directorio WEB-INF de la aplicación de ejemplo “sampleapp”, como se puede ver a continuación:

Page 269: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 269 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

88 Path del fichero jaas-config.xml

A continuación se muestra el contenido de este fichero incluido en la aplicación de ejemplo “sampleapp”. <!DOCTYPE jaas PUBLIC "-//Framework PA - Team//DTD JAAS Config uration 1.3F//ES" "jaas-config.dtd"> <jaas>

Page 270: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 270 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<application name="Carrito" controlFlag="required" > <module>es.princast.framework.modules.security.sta ndalone.StandaloneLoginModule</module> <options> <option> <name>USERS.FILE</name> <value>WEB-INF/authorized-users.xml</value> </option> <option> <name>LOOKUP.FILE.MODE</name> <value>WEBAPP.CONTEXT</value> </option> </options> </application> </jaas> En este fichero se definen los módulos de configuración a utilizar. Cada módulo se define con la etiqueta <application ..>. Cuando se vaya a autenticar a un usuario, se utilizará el módulo cuyo valor del atributo “name” coincida con el parámetro app-config (de los parámetros básicos de autenticación, ver sección anterior). Eventualmente, el atributo “controlFlag” está desactivado. No se tiene en consideración el valor especificado para realizar la autenticación. Para cada módulo, es obligatorio indicar el nombre de la clase que implementa la lógica de autenticación, utilizando la etiqueta anidada: <module>. Esta clase debe implementar el interface LoginModule, definido en el paquete JAAS. Por último, en la etiqueta <options> se pueden definir todas las opciones de configuración específicas del módulo JAAS que se vaya a utilizar. Por defecto, en la aplicación de ejemplo y en la aplicación en blanco, las credenciales de los usuarios están definidas en el fichero WEB-INF/authorized-users.xml. A continuación se muestra el contenido del fichero autorized-user.xml incluido en la aplicación de ejemplo “sampleapp”. <!DOCTYPE users PUBLIC "-//Framework PA - Team//DTD Authorized Users Configuration 1.3F//ES" "authorized-users.dtd"> <users> <user username="cliente" password="cliente" type=" CITIZEN">

Page 271: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 271 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<principals> <principal name="USERNAME" value="cliente"/> <principal name="SURNAME1" value="Lopez"/> <principal name="SURNAME2" value="Otro"/> <principal name="NIF/NIE" value="12345678Z" identifier="true"/> <principal name="ID THIRD PARTY" value="12345"/> <principal name="AGENT USER TYPE" value="CITIZEN USER TYPE"/> <principal name="ORGANIZATIONAL UNIT ID" value=" 1001"/> <principal name="ORGANIZATIONAL UNIT NAME" value="Consejería de Infraestructuras"/> </principals> <roles> <role name="Citizen"> <domainRole name="grupo1" value="grupo1" procedure="no"/> </role> </roles> </user> <!—

Ejemplo de citizen para escenario de autenticac ión con nivel 0.5 -->

<user username="28356558L" password="01/01/2010" t ype="CITIZEN"> <principals> <principal name="USERNAME" value="interop"/> <principal name="SURNAME1" value="Uno"/> <principal name="SURNAME2" value="Otro"/> <principal name="NIF/NIE" value="28356558L" identifier="true"/> <principal name="ID THIRD PARTY" value="12345"/> <principal name="AGENT USER TYPE" value="CITIZEN USER TYPE"/> <principal name="ORGANIZATIONAL UNIT ID" value=" 1001"/> <principal name="ORGANIZATIONAL UNIT NAME" value="Consejería de Infraestructuras"/> <!-- Principals nuevos --> <principal name="NATIONALITY" value="Spain"/> <principal name="SEX" value="Male"/> <principal name="DATE OF BIRTH" value="01/01/197 0"/> <principal name="LOCALITY OF BIRTH" value="Madri d"/> <principal name="PROVINCE OF BIRTH" value="Madri d"/> <principal name="NAME OF FATHER" value="Jose"/> <principal name="NAME OF MOTHER" value="Ines"/>

Page 272: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 272 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<principal name="LOCALITY OF ADDRESS" value="Mad rid"/> <principal name="PROVINCE OF ADDRESS" value="Mad rid"/> <principal name="STREET OF ADDRESS" value="Calle Mayor"/> <principal name="EXPIRY DATE OF NIF/NIE" value="01/01/2011"/> </principals> <roles> <role name="Citizen"> <domainRole name="grupo1" value="grupo1" procedure="no"/> </role> </roles> </user> </users>

15.1.3.2.3. Reglas de Seguridad

Por último, es necesario configurar las reglas de seguridad que definirán que recursos de la aplicación están protegidos, y de que forma. Un recurso sólo puede estar protegido una vez. Si una URL encaja en varios patrones definidos en el fichero de reglas de seguridad, se tendrá en cuenta el patrón más restrictivo. Para configurar las reglas de seguridad, se debe definir, en el fichero princast-init-script.xml, un plug-

in de configuración de tipo: SecurityRulesConfigurationPlugin. Por ejemplo: <bean id="securityRulesPlugin" class="es.princast.framework.web.filter.security.co rp.conf.SecurityRulesConfigurationPlugin"> <constructor-arg><value>security-rules</value></co nstructor-arg> <property name="file"> <value>WEB-INF/princast-security-rules.xml</value >

</property> <property name="contexts"> <list> <value>SECURITY</value> </list> </property> </bean>

Page 273: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 273 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Las reglas de seguridad se definirán, por su lado, en el fichero princast-security-rules.xml, disponible en el directorio WEB-INF:

Page 274: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 274 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

89 Path del fichero princast-security-rules.xml

Page 275: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 275 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

A continuación vemos el contenido del fichero princast-security-rules.xml disponible en la aplicación de ejemplo sampleapp: <!DOCTYPE resources PUBLIC "-//Framework PA - Team//DTD Security Ru les Configuration 1.3F//ES" "princast-security-rules.dtd"> <resources> <!-- Acceso para ciudadanos --> <resource actor="CITIZEN" level="0"> <url-pattern>/*</url-pattern> </resource> <resource actor="CITIZEN" level="0"> <url-pattern>/action/viewlistaproductoxml</url-pa ttern> </resource> <resource actor="CITIZEN" level="1"> <url-pattern>/action/*</url-pattern> <forwards> <forward name="login" path="/pages/login.jsp" /> <forward name="error" path="/pages/error.jsp" /> <forward name="no-login" path="/pages/login.jsp" /> <forward name="no-roles" path="/pages/noroles.js p" /> </forwards> </resource> <resource actor="CITIZEN" level="1"> <url-pattern>/dwr/*</url-pattern> <forwards> <forward name="login" path="/pages/login.jsp" /> <forward name="error" path="/pages/error.jsp" /> <forward name="no-login" path="/pages/login.jsp" /> <forward name="no-roles" path="/pages/noroles.js p" /> </forwards> </resource> </resources> En este fichero, cada etiqueta <resource> define un recurso protegido. Un recurso tiene tres atributos: actor, nivel de seguridad y protocolo.

Page 276: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 276 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

El atributo “actor” define el usuario-tipo que va a acceder al recurso. En función de este valor, el proceso de autenticación puede ser diferente. La semántica exacta de este atributo la establece el módulo JAAS que realice la autenticación. El atributo “level”, define el nivel de protección establecido para el recurso. Generalmente, hay 3:

• nivel 0 para recursos sin protección. • nivel 1 para recursos protegidos bajo par usuario/contraseña. • nivel 2 para recursos protegidos con certificado digital.

Generalmente, un nivel de seguridad permite el login por los mecanismos para sí definidos y también mediante los definidos para niveles superiores. Por ejemplo, un recurso protegido bajo usuario/contraseña también será accesible con certificado digital. La semántica exacta del nivel de seguridad, la define el módulo JAAS. El protocolo (atributo “protocol”) define el tipo de acceso deseado al recurso. Puede tomar dos valores: “http” si no se quiere ninguna encriptación del recurso o “https” si se desea garantizar la privacidad de los datos transmitidos entre el cliente y la aplicación. Este atributo puede omitirse, en tal caso, se permite el acceso al recurso bajo cualquier protocolo. Un recurso protegido es, exactamente, un patrón URL que se aplica sobre el espacio de direcciones de la aplicación. Este patrón URL se define en la etiqueta anidada <url-pattern>. Si, en un mismo fichero de reglas, varios patrones, de varios recursos, coinciden, el recurso que se utiliza para autenticar es el que defina el patrón más restrictivo de todos. Cuando se produce un error autenticando al usuario, en función de la naturaleza de dicho error, el Filtro de Seguridad, actuará redireccionando a un path determinado. Por ejemplo, si no se puede autenticar al usuario porque la contraseña es incorrecta, se le redirigirá a una página donde se muestra el formulario de entrada. Sin embargo, si no se puede autenticar al usuario porque no tiene privilegios suficientes (roles) para acceder a un recurso, se le puede redireccionar a otra página distinta informándole de dicha situación. Las redirecciones se especifican bajo la etiqueta “<forwards>”. Cada redirección tendrá un nombre que la identifica (“name”) y una URL a la que se redirigirá al usuario (“path”). Los nombres de forwards válidos son:

• login. Se redirige a login la primera vez que un usuario trata de acceder a un recurso protegido. • no-login. Esta redirección se ejecuta cuando no se puede autenticar al usuario por cualquier

motivo (por ejemplo, contraseña equivocada).

Page 277: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 277 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• no-roles. Se redirige a este forward cuando el usuario, que está correctamente autenticado, no tiene autorización para acceder al recurso.

• error. Esta redirección está reservada a situaciones de autenticación no controladas por los forwards definidos para el recurso. Si no se define forward de error, cuando se de un fallo de autenticación, se devolverá un error http 515.

En cada recurso también se definirán los nombres de los roles que tienen acceso. Si no se incluye la etiqueta <roles>, no se realizará chequeo de roles. Por último, se pueden definir las opciones de configuración (<options>) que se estimen convenientes para el recurso. La semántica de estas opciones depende exclusivamente del módulo JAAS que realiza la operación de login.

15.1.3.3. Paso de Credenciales

Durante el proceso de autenticación, se recaba una serie de datos del usuario. Estos datos se guardan en la sesión http en un objeto de tipo javax.security.auth.Subject, bajo la clave SecurityGlobals.SUBJECT. Para recuperar las credenciales de los usuarios se utiliza el filtro "LoginFilter", llamando al método “populateUserVO” de la clase “UserVOLoader”, como podemos ver a continuación. public class LoginFilter extends PrincastFilter imp lements LoginFilterMBean {

protected void filter(ServletRequest req, ServletRe sponse resp, FilterChain chain) throws IOException, ServletException { if (!(req instanceof HttpServletRequest)) { chain.doFilter(req, resp); return; } HttpServletRequest request = (HttpServletRe quest) req; UserVO user = new UserVO(); // Se obtiene el subject Subject subject = (Subject) request.getSess ion(true).getAttribute( SecurityGlobals.SUBJECT); // Cargamos sus credenciales. if (subject == null) {

Page 278: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 278 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

// el usuario todavia no está autentica do chain.doFilter(req, resp); return; } UserContainer existingContainer = UserConta iner .getUserContainer(request); // si ya cargue los datos anteriormente ent onces retorno if (existingContainer.getUserVO() != null) { chain.doFilter(req, resp); return; } UserVOLoader.populateUserVO(user, subject); if (this.logger.isDebugEnabled()) { this.logger.debug("Se ha autentificado al usuario:\n" + user.toXML()); } existingContainer.setUserVO(user); chain.doFilter(req, resp);

} } Como podemos ver en el método “populateUserVO” de la clase “UserVOLoader” que se muestra a continuación, se recuperan las credenciales del usuario, y los roles definido en el fichero “autorizad-

user.xml”, para el usuario que ha accedido al sistema. Para recuperar las diferentes credenciales almacenadas en el objeto de tipo “javax.security.auth.Subject”, basta con emplear las diferentes constantes definidas en la clase SecurityConstants como parámetros para las llamadas al método getPrincipal() de la clase Principals contenida en el objeto “Subject”. public static void populateUserVO(UserVO user, Subj ect subject) { Set principals =

subject.getPrincipals(PrincastCompositePrincipal.cl ass); if (principals.isEmpty()) { logger.error("No hay principals en el subj ect");

Page 279: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 279 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

throw new UnmanagedLoginException(UserVOL oader.class, "buscando principals", "no se han encontrado principals" );

} PrincastCompositePrincipal principal = (PrincastCompositePrincipal) principals.iterat or().next(); String val = principal.getPrincipal(SecurityConsta nts.NAME); if (val != null) { user.setName(val); } val = principal.getPrincipal(SecurityConstants.SUR NAME1); if (val != null) { user.setFirstName(val); } val = principal.getPrincipal(SecurityConstants.SUR NAME2); if (val != null) { user.setLastName(val); } val = principal.getPrincipal(SecurityConstants.NIF NIE); if (val != null) { user.setUserName(val); } val =

principal.getPrincipal(SecurityConstants.ORGANIZATI ONAL_UNIT_NAME); if (val != null) { user.setOrganizationalUnit(val); } // Roles del usuario Set roles = subject.getPrincipals(PrincastGroup.cl ass); String nombreRoles = ""; if (logger.isDebugEnabled()) { logger.debug("--> Roles del usuario: "); } Iterator it = roles.iterator(); while (it.hasNext()) { Group rol = (Group) it.next(); nombreRoles = nombreRoles + " " + rol.getName(); if(logger.isDebugEnabled()) {

Page 280: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 280 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

logger.debug("\t" + rol.getName()); } } user.setRoles(nombreRoles); user.setEmailAddress(UNKNOWN); principals = subject.getPrincipals(ScenarioPrincip al.class); ScenarioPrincipal scenario =

(ScenarioPrincipal) principals.iterator().next(); user.setChannel(scenario.getChannel()); }

Atención

No es recomendable obtener los datos de autenticación (j_username y j_password) directamente de los parámetros de la request. No se garantiza que estos datos vayan a ser los correctos. Además, en openFWPA, cualquier parámetro que se utilice como contraseña será enmascarado (reemplazado por la cadena "*********") por el filtro de autenticación.

15.1.3.4. Diseño de páginas de login

En las aplicaciones que utilicen openFWPA, las páginas de login deben escribirse en páginas JSP para la obtención de los datos de autentificación (filtro "LoginFilter" visto anteriormente).

90 Página de login de la aplicación de ejemplo de openFWPA

Con el fin de facilitar el diseño e implementación de estas páginas, se utilizan varias etiquetas incluidas en el fichero princast-ui.tld, como por ejemplo ui:layout-area, ui:block-row ó ui:block-

column, así como un conjunto de clases CSS definidas en el fichero login.css.

Page 281: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 281 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

El filtro de autenticación deja, en el scope session, la URL del recurso protegido solicitado, al que se estaba intentando acceder. El nombre del atributo bajo el que se almacena esta URL está definido por la constante: SecurityGlobals.REQUESTED_URL. A continuación se muestra el contenido del body de la página “login.jsp” de la aplicación de ejemplo “sampleapp” de openFWPA. <ui:errors/> <form id="mainForm" action="<%if(session.getAttribute(SecurityGlobals.R EQUESTED_URL)==null){out.print("../action/viewperfil");}else out.print(session.getAttribute(SecurityGlobals.REQU ESTED_URL));%>" method="post"> <div id="exterior"> <div id="interior"> <h1><bean:message key="login.body"/></h1> <princast:instanceOf

variableName="<%=SecurityGlobals.LOGIN_EXCEPTION%>" className="es.princast.framework.facilities.securi ty.exceptions.PrincastLoginException"> <div id="errors" class="errors"> <bean:message key="error.login.titulo"/>: <princast:instanceOf variableName="<%=SecurityGlobals.LOGIN_EXCEP TION%>" className="es.princast.framework.facilities.secur ity.exceptions. WrongPasswordException"> <ul><li> <bean:message key="error.login.WrongPas swordException"/> </li></ul> </princast:instanceOf> <princast:instanceOf variableName="<%=SecurityGlobals.LOGIN_EXCEP TION%>" className="es.princast.framework.facilities.s ecurity.exceptions. InsufficientPrivilegesException"> <ul><li> <bean:messagekey="error.login.InsufficientPri vilegesException"/> </li></ul> </princast:instanceOf> <princast:instanceOf variableName="<%=SecurityGlobals.LOGIN_EXCEP TION%>" className="es.princast.framework.facilities.s ecurity.exceptions. InsufficientDataException">

Page 282: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 282 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<ul><li> <bean:message key="error.login.Insuffici entDataException"/> </li></ul> </princast:instanceOf> <princast:instanceOf variableName="<%=SecurityGlobals.LOGIN_EXCEP TION%>" className="es.princast.framework.facilities.s ecurity.exceptions. UnknownUserException"> <ul><li> <bean:message key="error.login.UnknownU serException"/> </li></ul> </princast:instanceOf> <princast:instanceOf variableName="<%=SecurityGlobals.LOGIN_EXCEP TION%>" className="es.princast.framework.facilities.s ecurity.exceptions. UnmanagedLoginException"> <ul><li> <bean:message key="error.login.Unmanage dLoginException"/> </li></ul> </princast:instanceOf> </div> <!-- div errors --> <!-- No queremos que muestre el error la primer a vez que se

muestra la pantalla de login. --> <princast:instanceOf

variableName="<%=SecurityGlobals.LOGIN_EXCEPTION %>" className="es.princast.framework.facilities.sec urity.exceptions. RequiredPasswordException"> <script type="text/javascript"> document.getElementById('errors').style.d isplay = "none"; </script> </princast:instanceOf> </princast:instanceOf> <div id="loginPanel" class="panel "> <div class="panel_caption"> <h2 class="panel_caption_login_text"> <bean:message key="login.caption"/> </h2> </div> <div id="loginPanelBody" class="panel_body"> <ui:layout-area> <ui:block-row cssClass="item_row loginPan elRow"> <label for="j_username">

Page 283: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 283 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

<bean:message key="login.user.label " /> </label> <input type="text" id="j_username" nam e="j_username"/> </ui:block-row> <ui:block-row cssClass="item_row loginPan elRow"> <label for="j_password"> <bean:message key="login.password.l abel" /> </label> <input type="password" id="j_password" name="j_password"/> </ui:block-row> </ui:layout-area> <div class="item_pie"> </div> </div> </div> <!-- div loginPanel--> <hr/> <div class="buttons"> <html:image src="images/botones/enter-button.gi f" altKey="button.entrar" styleClass="button_login _text"/> </div> </div> <!-- div interior --> <div id="footer"> <ui:layout-area id="desplazamiento"> <ui:block-row> <ui:block-column > <img src="images/alerta.gif" alt="Alerta" /> </ui:block-column > <ui:block-column cssClass="footer_text_login " > &nbsp;&nbsp;<bean:message key="login.foot er"/> </ui:block-column > </ui:block-row> </ui:layout-area> </div> <!-- div footer--> </div> <!-- div exterior --> </form>

Page 284: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 284 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

15.1.3.5. Excepciones durante el proceso de autenticación

Ver apartado "13.2. Excepciones durante el proceso de autenticación".

15.1.3.6. Niveles de Seguridad

Para la autenticación se contemplan tres niveles de seguridad:

• Nivel 0. Con este nivel de seguridad no se requiere autenticación. • Nivel 1. Con este nivel es necesaria la validación mediante usuario y contraseña. Para ello,

deben especificarse dos parámetros denominados j_username y j_password con dicha información.

• Nivel 2. Este nivel de seguridad se corresponde a la autenticación utilizando certificado digital. Debe tratarse de un certificado digital válido de la FNMT (Fábrica Nacional de la Moneda y Timbre). Para forzar a esta validación debe incluirse en la petición http un parámetro denominado forceLevel con el valor 2.

Un ejemplo de uso de este nivel de seguridad se presenta a continuación: http://localhost:8082/prueba/action/suscribe?forceL evel=2

16. Pruebas de rendimiento

Las pruebas de rendimiento son aquellas que se realizan para medir el tiempo que tarda una determinada tarea en ejecutarse bajo unas condiciones determinadas de trabajo. También sirve para verificar que el sistema cumple los criterios de rendimiento, comparar dos sistemas para encontrar cual de ellos funciona mejor, medir que partes del sistema o de carga de trabajo provocan que el conjunto rinda mal, la escalabilidad del sistema o analizar la fiabilidad y uso de los recursos. Por tanto, los principales objetivos de las pruebas de rendimiento son:

• Asegurar que la infraestructura de sistemas y comunicaciones está preparada para albergar la aplicación.

• Ayuda a detectar bugs como “memory leaks” o una mala gestión de conexiones (muy habitual).

• Información importante para la toma de decisiones y gestión de riesgos del equipo de sistemas con la aplicación en producción.

Page 285: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 285 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

Ejemplo de indicadores analizados habitualmente en las pruebas de rendimiento:

• Ancho de banda consumido por usuario. • Degradación del tiempo de respuesta en función del número de usuarios. • Degradación de la calidad del servicio frente al número de usuarios. • Cómo decrece el % peticiones respondidas. • Punto de saturación (número de usuarios donde los tiempos de respuesta o la calidad del

servicio están fuera de lo considerado aceptable por la aplicación). Para alcanzar un buen nivel de rendimiento de un nuevo sistema, es fundamental que los esfuerzos en estas pruebas comiencen en el inicio del proyecto de desarrollo y se amplie durante su construcción. Cuanto más se tarde en detectar un defecto de rendimiento, mayor es el coste de la solución. Esto es cierto en el caso de las pruebas funcionales, pero mucho más en las pruebas de rendimiento, debido a que su ámbito de aplicación es de principio a fin. Sin embargo, muchos desarrolladores no siguen esta recomendación, porque por ejemplo ven las pruebas aburridas, innecesarias o confían en que su codificación es correcta, y deciden realizar todas las pruebas al finalizar el desarrollo, momento en que se detectan todos los problemas, es dificil diagnosticar las causas de los fallos, los costes de solucionar los problemas son muy elevados, …, obteniendo un producto final defectuoso. Antes de realizar las pruebas de rendimiento de nuestra aplicación, debemos tener una visión global del proyecto, identificar los escenarios en los que tendrá lugar la aplicación, conover las razones por las que debemos hacer las pruebas de rendimiento, …, para planificar y diseñar el plan de pruebas e identificar los criterios de. Un desarrollo estable de la aplicación instalado en un entorno lo más parecido al de producción. El entorno de pruebas de rendimiento no debe cruzarse con pruebas de aceptación de usuarios ni con el entorno de desarrollo. Esto es tan peligroso que si las pruebas de aceptación de usuarios, o las pruebas de integración o cualquier otra prueba se ejecutan en el mismo entorno, entonces los resultados no son fiables. Como buena práctica, siempre es aconsejable disponer de un entorno de pruebas de rendimiento lo más parecido como se pueda al entorno de producción. Finalmente, tras ejecutar el plan de pruebas, es muy importante analizar los resultados obtenidos, identificar puntos de mejora, sacar conclusiones, y volver a ejecutar las pruebas hasta obtener los resultados satisfactorios.

Page 286: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 286 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

16.1. Tipos de pruebas

16.1.1. Pruebas de carga

Este es el tipo más sencillo de pruebas de rendimiento. Una prueba de carga se realiza generalmente para observar el comportamiento de una aplicación bajo una cantidad de peticiones esperada. Esta carga puede ser el número esperado de usuarios concurrentes utilizando la aplicación y que realizan un número específico de transacciones durante el tiempo que dura la carga. Esta prueba puede mostrar los tiempos de respuesta de todas las transacciones importantes de la aplicación. Si la base de datos, el servidor de aplicaciones, etc también se monitorizan, entonces esta prueba puede mostrar el cuello de botella en la aplicación.

16.1.2. Prueba de estrés

Esta prueba se utiliza normalmente para romper la aplicación. Se va doblando el número de usuarios que se agregan a la aplicación y se ejecuta una prueba de carga hasta que se rompe. Este tipo de prueba se realiza para determinar la solidez de la aplicación en los momentos de carga extrema y ayuda a los administradores para determinar si la aplicación rendirá lo suficiente en caso de que la carga real supere a la carga esperada.

16.1.3. Prueba de estabilidad (soak testing)

Esta prueba normalmente se hace para determinar si la aplicación puede aguantar una carga esperada continuada. Generalmente esta prueba se realiza para determinar si hay alguna fuga de memoria en la aplicación.

16.1.4. Pruebas de picos (spike testing)

La prueba de picos, como el nombre sugiere, trata de observar el comportamiento del sistema variando el número de usuarios, tanto cuando bajan, como cuando tiene cambios drásticos en su carga. Esta prueba se recomienda que sea realizada con un software automatizado que permita realizar cambios en el número de usuarios mientras que los administradores llevan un registro de los valores a ser monitorizados.

16.2. Herramientas

Las pruebas de rendimiento de aplicaciones Web, se deben realizar, de forma automatizada, utilizando herramientas inyectoras de carga, como por ejemplo Apache Meter, Opensta o JAMon.

• Apache JMeter [http://jmeter.apache.org/] es una herramienta de escritorio desarrollada en Java, diseñada para realizar pruebas de rendimiento y pruebas funcionales sobre aplicaciones

Page 287: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 287 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

en entorno Web. Apache JMeter se puede utilizar para medir el rendimiento de recursos dinámicos y estáticos (archivos, Servlets, scripts de Perl, Objetos Java, bases de datos y consultas, servidores FTP,…). Se puede utilizar para simular una carga pesada en un servidor, ,… , y poner a prueba su resistencia o analizar el rendimiento general con distintos tipos de carga. JMeter destaca por su versatilidad, estabilidad y por se de uso gratuito.

• Opensta (Open System Testing Architecture) con licencia GNU General Public License y lo

podemos encontrar en (http://www.opensta.org). Es una herramienta basada en arquitectura CORBA que permite realizar pruebas de carga y pruebas de estrés en aplicaciones Web.

• JAMon Java Applicaton Monitor [http://jamonapi.sourceforge.net] es una herramienta libre,

que permite ver claramente los tiempos entre capas, cuanto tiempo tarda en ejecutarse un determinado EJB o un JSP o un Servet. Cuanto tarda la BBDD en ejecutar cierta consulta y pasarla a la clase que le ha pedido, etc. Es una herramienta sencilla utilizar, y permite trabajar con distintos servidores de aplicaciones (Sybase EAServer, BEA Weblogic, Tomcat, JBoss, ...).

• …

16.3. Pruebas de rendimiento en openFWPA

Para realizar pruebas de rendimiento en openFWPA, hay que poner el parámetro de configuración PERFORMANCE.TEST.MODE al valor ON. Este parámetro se puede definir en cualquier plug-in de configuración que sirva parámetros al contexto de seguridad: SECURITY. Por ejemplo, en la aplicación de ejemplo lo tenemos comentado por defecto en el fichero “carrito.properties” comentado anteriormente, como podemos ver a continuación. # #Fri Jan 07 10:08:36 CET 2005 CARRITO.AGENCIA=Manin Directo. app-config=Carrito DEFAULT.MENU=MenuMiPerfil ITEM.SEPARATOR = &gt; JMX.SERVER.NAME = SampleApp #PERFORMANCE.TEST.MODE = ON URL_LOGOUT=/carrito #Configuracion de cache CACHE_CONF=classpath:/ehcache.xml #Tamaño de página para displayTag PAGE_SIZE=10

Page 288: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 288 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

17. Anexo: Consola de gestión de Tomcat 7

Se recomienda a los administradores de sistemas utilizar la consola de gestión de Apache Tomcat para facilitar la monitorización y gestión “en caliente” de las aplicaciones. … Para acceder al gestor de aplicaciones Web de Tomcat 7, pulsaremos en el botón “Manager App” disponible en la zona derecha de la pantalla, tal y como podemos ver en la siguiente imagen.

91 Sección Manager App

Aparecerá una ventana emergente en la tendremos que introducir el usuario y la contraseña que previamente hemos introducido en el fichero “tomcat-users.xml” (ver Manual de instalación de

openFWPA en Windows/Linux).

Page 289: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 289 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

92 Identificación de usuario en Tomcat 7

Tras identificarnos, accederemos al gestor de aplicaciones Web de Tomcat 7.

Page 290: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 290 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

93 Gestor de aplicaciones Web de Tomcat 7

La interfaz para la gestión de aplicaciones Web de Tomcat 7 consta de varios apartados, que se comentarán brevemente a continuación. Para más información, acceder a http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html.

17.1. Mensajes

En esta sección se mostrarán los mensajes que nos informarán del estado de las acciones que se realicen en el gestor de aplicaciones Web del Tomcat 7.

94 Sección de mensajes del gestor de aplicaciones Web de Tomcat 7

17.2. Gestor

Esta sección se divide en cuatro apartados.

95 Sección de gestión del gestor de aplicaciones Web de Tomcat 7

Page 291: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 291 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

• Lista de aplicaciones. Tras pulsar en este enlace, se recargará la lista de aplicaciones que se muestran en el bloque siguiente, y que se verá en el próximo apartado.

• Ayuda HTML del Gestor. Enlace a una página local de ayuda [http://localhost:8082/docs/html-

manager-howto.html] donde se explica más en detalle el gestor de aplicaciones Web de Tomcat.

• Ayuda del Gestor. Enlace a una página local de ayuda [http://localhost:8082/docs/manager-

howto.html] donde, de manera similar al enlace anterior, se explica el gestor de aplicaciones Web de Tomcat.

• Estado del Servidor. Este enlace nos permite ve el estado del motor del servidor.

96 Estado del servidor Tomcat 7

17.3. Aplicaciones

En esta sección se muestra el listado de aplicaciones Web disponibles en Apache Tomcat 7.

Page 292: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 292 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

97 Sección de aplicaciones del gestor de aplicaciones Web de Tomcat 7

Para cada aplicación se muestra la siguiente información:

• Trayectoria. Es la ruta del contexto de la aplicación. • Nombre a mostrar. Nombre configurado en el fichero “web.xml” para la aplicación. • Ejecutándose. Será “trae” si la aplicación Web se está ejecutando, y “false” si la aplicación no

está en ejecución o no está disponible. • Sesiones Número de sesiones activas en la aplicación Web. Este número de sesiones activas es

un enlace que muestra la información ampliada sobre estas sesiones activas.

98 Detalle de las sesiones activas para un proyecto determinado

• Comandos. Para cada aplicación tendremos disponibles cuatro comandos, que nos permitirán gestionar las aplicaciones Web disponibles en el servidor.

Page 293: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 293 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

o Start. – Arrancar una aplicación Web que ha sido detenida. o Stop. Detener una aplicación Web que actualmente está en ejecución, dejándola

inaccessible para los visitantes. o Reload. Recargar el contexto de la aplicación Web, de forma que por ejemplo estarán

disponibles nuevos fichero “.jar” en el directorio “/WEB-INF/lib/” o nuevas clases en el directorio “/WEB-INF/classes/” de la aplicación.

o Undeploy. Detener una aplicación Web y eliminar todas las referencia a la misma del servidor.

17.4. Desplegar

Desde esta sección se pueden realizar despliegues de las aplicaciones Web utilizando ficheros o directorios ya existentes en el servidor Tomcat, o bien subiendo un fichero de tipo “WAR” (web

application archive) al servidor. Como podemos ver en la siguiente imagen, tras completar correctamente el formulario (en función de la forma seleccionada para realizar el despliegue), tendremos que pulsar en el botón “Desplegar”.

99 Sección de despliegues del gestor de aplicaciones Web de Tomcat 7

17.4.1. Despliegue utilizando un directorio o un fichero WAR del propio servidor Tomcat

17.4.1.1. Despliegue mediante el directorio o la URL del fichero WAR

En esta sección se comentará como instalar un directorio de una aplicación Web o un fichero WAR localizados en el propio servidor Tomcat. Si el apartado “Trayectoria del contexto”, que es opcional, no se completa, se tomará el nombre del fichero, eliminando la extensión “.war”.

Page 294: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 294 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

La URL del WAR o del directorio debe seguir el esquema “file:” disponible por ejemplo en el Javadoc para la clase “java.net.JarURLConnection”: http://docs.oracle.com/javase/1.4.2/docs/api/java/net/JarURLConnection.html. A continuación vamos a ver un ejemplo de una aplicación Web disponible en el directorio “/<path>/to/foo” en el servidor Apache Tomcat, que será desplegada bajo el nombre de contexto “/footoo” (Linux). Trayectoria del Contexto (opcional): /footoo URL del WAR o Directorio: file:/<path>/to/foo Ahora veremos otro ejemplo para un fichero WAR disponible en el servidor Tomcat en el directorio “/home/<path>/to/bar.war”. En este caso no introduciremos nombre para el Contexto, y por tanto la aplicación estará disponible bajo el contexto “/bar”, ya que el fichero se llama “bar.war”, y se quitará automáticamente la extensión “.war” (Linux). URL del WAR o Directorio: jar:file:/<path>/to/bar.w ar!/

17.4.1.2. Despliegue mediante el directorio o la URL en el directorio base de Tomcat

En esta sección se comentará como instalar un directorio de una aplicación Web o un fichero WAR localizados en el directorio base del propio servidor Tomcat, que habitualmente se llama “webapps” Al igual que en el apartado anterior, si el apartado “Trayectoria del contexto” no se completa, se tomará el nombre del fichero, eliminando la extensión “.war”. A continuación vamos a ver un ejemplo de una aplicación Web disponible en el directorio base en el servidor Apache Tomcat, que será desplegada bajo el nombre de contexto “/foo” (en este caso no introducimos el nombre del contexto, y se toma el nombre del directorio). URL del WAR o Directorio: foo Ahora veremos otro ejemplo para un fichero WAR disponible en el directorio base del servidor Tomcat. En este caso si introduciremos nombre para el Contexto “bartoo”, y por tanto la aplicación estará disponible bajo el contexto “/bartoo”. Trayectoria del Contexto (opcional): bartoo URL del WAR o Directorio: bar.war

Page 295: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 295 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

17.4.1.3. Despliegue mediante URL de archivo de configuración XML

Si el flag “deployXML” está puesto a “true”, se podrán utilizar ficheros XML de configuración de contexto para realizar el despliegue de aplicaciones Web. Este parámetro se puede actualizar añadiéndolo en el fichero “Server.xml” en la línea que empieza por: <Host appBase="webapps" autoDeploy="true" name="loc alhost" unpackWARs="true" ... Para más información ver: http://tomcat.apache.org/tomcat-7.0-doc/config/host.html#Standard_Implementation Al realizar el despliegue mediante el archivo de configuración XML, se ignora el texto introducido en el campo opcional “Trayectoria del Contexto”. A continuación se muestra un ejemplo de fichero XML de configuración del contexto para una aplicación Web. <Context path="/foobar" docBase="/path/to/applicati on/foobar"> </Context> A continuación se muestra un ejemplo de despliegue de una aplicación Web a través de un fichero de contexto (Linux). URL de archive de Configuración XML: file:/home/<pa th>/foobar.context.xml

17.4.2. Desplegar a través de un archive WAR externo

A través de esta sección se realizará el despliegue de una aplicación Web en el servidor Apache Tomcat utilizando un fichero WAR que se encuentre en el sistema de archivos del desarrollador, a través del botón examinar que está disponible en este apartado. El nombre del contexto de la aplicación será por tanto el nombre del fichero, pero eliminando la extensión “.war”.

17.5. Diagnósticos

Esta sección permite revisar si las aplicaciones Web han provocado algún fallo de memoria al parar, recargar, …

Page 296: 04. ManualConfiguracion openFWPA 20111230 v1...Proyecto OpenFWPA Internacional openFWPA Página 2 de 296 Estado Definitivo Documento Manual de Configuración Cluster TIC () 04.

Proyecto OpenFWPA Internacional

openFWPA

Página 296 de 296

Estado Definitivo

Documento Manual de Configuración

Cluster TIC (www.clustertic.net) 04. ManualConfiguracion_openFWPA_20111230_v1.0.docx 30/12/2011

100 Sección de diagnósticos del gestor de aplicaciones Web de Tomcat 7

Más información en http://tomcat.apache.org/tomcat-7.0-doc/html-manager-howto.html#Diagnostics.

17.6. Información del servidor

This section displays information about Tomcat, the operating system of the server Tomcat is hosted on, and the Java Virtual Machine Tomcat is running in. Esta sección muestra la información del Servidor Tomcat, el sistema operativo del servidor donde está alojado, la máquina virtual donde está corriendo, …

101 Sección de información del servidor del gestor de aplicaciones Web de Tomcat 7