Normativa - Comunidad de Madrid

Anuncio
ATLAS
Normativa
Versión 1.17
(Corresponde a Versión de ATLAS 1.2.6)
Arquitectura de Software
Framework Atlas
Normativa
Hoja de Control
Título
NORMATIVA
Documento de
Referencia
Responsable
Arquitectura de Software
Versión
1.17
Fecha Versión
08/05/2014
Registro de Cambios
Versión
Responsable del
Causa del Cambio
Cambio
Fecha
Área de Aplicaciones
1.0
Versión inicial del documento, se parte de la
normativa creada antes de desarrollar el
framework
Especiales y
Arquitectura de
24/05/2010
Software
Modificaciones sobre versión 1.0:
-
Norma: JSFHttpSession: Se cambia la
redacción de la norma ya que podía
malinterpretarse.
-
Norma: JSFNavegacion: Se modifica la
nomenclatura de la clase para el caso de
haber varios bloques funcionales.
Área de Aplicaciones
Especiales y
1.1
-
-
Norma: SNDependencias: Se modifica la
norma para permitir varios ficheros de
contexto.
Arquitectura de
02/07/2010
Software
Norma: DAODependencias: Nueva
norma sobre versión 1.0. Se incluye una
norma para la nomenclatura del fichero de
contexto de los DAOS. Aunque esta
norma no existía el arquetipo ya venía con
esta nomenclatura.
Modificaciones sobre versión 1.1:
1.2
-
applicationContext-database.xml: Ya no
se anotan las clases, se hace por paquete
con la propiedad packagesToScan.
EntornoEjecucion: Se cambia de la jdk
de Sun a la jRockit.
Área de Aplicaciones
Especiales y
Arquitectura de
17/08/2010
Software
Se modifica la versión de la jdk y versión de
weblogic
1.3
Área de Aplicaciones
Modificaciones sobre versión 1.2:
-
Apartado 6.3.5: Se incluye un aviso al
2 de 198
Especiales y
31/08/2010
Framework Atlas
Normativa
Versión
Responsable del
Causa del Cambio
Cambio
final del apartado.
1.4
Fecha
Arquitectura de
-
Apartado 6.4.3: Nueva implementación en
la clase Cliente de los métodos equals /
hashcode / toString. Se añade una
recomendación a este respecto
-
Apartado 6.4.4: Se incluye información
sobre BaseDAO y se actualiza el código
correspondiente. Se adaptan las normas
según esta nueva implementación. Se
amplia la norma ADCatalogos para
indicar que no se debe borrar en cascada
sobre un catálogo.
-
Apartado 6.4.4.1: Nuevo apartado y
norma ADNamedParameter para uso
obligatorio de ‘named parameters’ en
consultas de BBDD.
-
Apartado 6.4.6.1: Se elimina un texto ‘El
siguiente ejemplo …’ en el apartado
6.4.6.1 que no tenía lugar ahí ya que está
prohibido su uso.
-
Norma Arquetipos: Añadido a la norma
requisito para arquetipo de proyectos.
-
Apartado 9.5: Nueva regla INTNomClient
Se incluyen las siguientes buenas practicas:
- JSFMessages
- JSFStoreError
- JSFAtlasFacesUtils
- JSFAccesoMessages
Que se refieren a la utilización de la clase
AtlasFacesUtils en distintos casos.
Software
Área de Aplicaciones
Especiales y
Arquitectura de
2/11/2010
Software
Modificaciones sobre versión 1.4:
-
Apartado 6.3.3: Se incluye nueva norma
SNSpringLIB sólo para módulos de tipo
librería
-
Apartado 6.3.3: Se modifica la norma
SNDependencias indicando que no aplica
a módulos de tipo librería
1.5
-
-
Apartado 6.4.2.3: Se modifica la norma
DAODependencias indicando que no
aplica a módulos de tipo librería
Apartado 7: Se modifica la norma
CONFNomenclatura sustituyendo nombre
de proyecto por nombre de módulo.
3 de 198
Área de Aplicaciones
Especiales y
Arquitectura de
Software
10/01/2011
Framework Atlas
Normativa
Versión
Responsable del
Causa del Cambio
Cambio
-
Apartado 7: Se incluyen dos nuevas
normas sobre las particularidades en la
configuración de los módulos de tipo
librería.
-
Apartado 5: Nueva norma
VERSIONADO.
-
Apartado 9.7.1: Se modifica la normativa
de acceso a Crystal Reports. Se modifica
la norma SOLRptConf.
Fecha
Modificaciones sobre versión 1.5:
-
Apartado 5: Se actualiza gráfico de
módulos para eliminar el sufijo intra. El
framework Atlas permite que el mismo
módulo sirva para intranet e Internet por lo
tanto este sufijo ya no tiene sentido.
Área de Aplicaciones
Especiales y
1.6
-
Apartado 6: Modificada norma
JSFJavascript.
-
Arquitectura de
25/04/2011
Software
Apartado 7: Modificada norma
CONFEntorno.
-
Apartado 10.1: Se incluye la posibilidad
de excluir la comprobación de normas en
la herramienta de validación.
Modificaciones sobre versión 1.6:
-
Apartado 8.1: Nueva norma
SBAutoPerfiles
-
Nuevo Apartado 6.3.6: Ficheros
temporales.
-
Apartado 6.3.6: Nueva norma
SNFicherosTemporales y nueva buena
1.7
práctica SNNomFicheroTemporal
-
Apartado 6.2.1: Nuevas buenas prácticas
JSFGet y JSFEL.
-
Apartado 6.2.1.9: Modificada buena
práctica JSFAjaxLimite.
-
Apartado 11.1 Tipos de pruebas:
Incluida nuevo tipo de prueba para las
4 de 198
Área de Aplicaciones
Especiales y
Arquitectura de
Software
21/09/2011
Framework Atlas
Normativa
Versión
Responsable del
Causa del Cambio
Cambio
Fecha
pruebas de los servicios web. Por lo tanto
se incluye una nueva norma
TestServicioWeb
-
Se actualiza el nombre del Area (Area
de Aplicaciones Especiales y Arquitectura
Software)
Modificaciones sobre versión 1.7:
-
Apartado 6.4.4: Modificado código fuente
de clases BaseDAO y BaseDAOImpl
1.8
-
Apartado 6.3.2: Incluidas en los
arquetipos las clases BaseService y
Área de Aplicaciones
Especiales y
Arquitectura de
24/02/2012
Software
BaseServiceImpl. Añadida la nueva buena
pràctica ADBaseService
-
Apartado 6.2.1: PAGINAS JSF: Se
eliminan las referencias a la librería de
componentes de JSF Tomahawk, ya que
ha dejado de utilizarse.
-
Apartado 6.2.3 Configuracion de JSF:
Se incluye la posibilidad de usar
anotaciones.
Área de Aplicaciones
-
Nuevo Apartado 6.2.3.5: Anotaciones.
-
Buena Práctica JSFMessages: Se
1.9
cambia el uso de t:message a h:message.
-
Buena Práctica JSFStoreError: Se
cambia el uso de t:message a h:message.
-
Buena Practica JSFSavestate Se
sustituye el uso del componente savestate
de tomahawk por una etiqueta propia de
atlas atlas:guardarEstado
-
Nuevo apartado 6.2.1.10: Ayuda
contextual.
1.10
-
Nueva buena practica JSFAYUDA
-
Modificado apartado 6.2.1.7 Uso de
5 de 198
Especiales y
Arquitectura de
Software
14/06/2012
Framework Atlas
Normativa
Versión
Responsable del
Causa del Cambio
Cambio
Fecha
Javascript para hablar de Jquery.
-
Nueva regla JSFJQuery
-
Nuevo apartado 10.3 Generación
automática de código
-
Apartado 6.3.1 Modificada norma
SNFacade para quitar que la fachada
debe gestionar la transaccionalidad.
Nueva buena practica SNFacadeWS que
recomienda no generar fachada en los
servicios web.
-
Apartado 6.2.1.8: Normas de estilo
Nueva norma JSFIFRAME que prohibe el
uso de IFRAMES.
-
Apartado 10: Servicios Web. Nuevo
apartado. Se añaden una nueva norma
WSSECURITY.
-
Apartado 9.3: Modificado Servicio de
Certificados digitales pasa a llamarse
Servicio de Criptografía. Se modifica el
texto de la norma SICert.
1.11
Apartado 8.1: Se incluye información
sobre los mecanismos implementados
01/03/2013
para cumplir los requisitos mínimos del
Esquema Nacional de Seguridad en el
acceso a las aplicaciones. Se crea nueva
norma SBENS.
-
Apartado 9.7.10: Envío de SMS. Se
modifica para que en lugar de invocar al
servicio web de mentes se utiliza un
servicio propio de Atlas llamado Servicio
de envío de SMS.
-
Apartado 9.7.11: Visor Mapas. Nuevo
componente.
1.12
-
Apartado 12: Entrega. Se cambia Unidad
6 de 198
25/03/2013
Framework Atlas
Normativa
Versión
Responsable del
Causa del Cambio
Cambio
Fecha
de Recepción de Aplicaciones por Unidad
de Paso a Producción y he informa acerca
de la creación de repositorio de
subversion.
-
Indice: Se regenera el indice ya que no
estaba bien.
1.13
-
Apartado 6.4.3.2: Se elimina la regla
ADLOB.
-
Apartado 9.7.8 XML sólo lectura
-
Apartado 6.2.1.8: Se modifica el nombre
29/05/2013
de la regla JSFAccesiblidad para incluir la
i que faltaba (JSFAccesibilidad).
-
Apartado A1.1: Se actualiza el nombre
de la regla en la lista de reglas.
-
Apartado 6.4.5: Modificada norma
ADStoredProc, se permite el uso de
CallableStatement en ciertos casos
1.14
-
Apartado 6.4.4: Modificada la norma
04/12/2013
ADSQLUso, si se permiten sentencias
SQL-DML
-
Apartado 6.2.2.3 Inicialización de los
Beans (@PostContruct)
-
Apartado 6.2.1.6 Nueva norma
JSFCustomMenu
-
Apartado 9.7.10 Añadida configuración
del environment.properties para envío de
correo
1.15
-
No estaban bien en el PDF generado los
marcadores a los manuales
-
18/12/2013
Nueva norma ADUsoAtlasLegacy para
requerir autorización excepcional para el
1.16
uso de la anotación @AtlasLegacy
-
Norma JSFPOB: Modificadas versiones
7 de 198
19/12/2013
Framework Atlas
Normativa
Versión
Responsable del
Causa del Cambio
Cambio
Fecha
mínimas de los browsers requeridos.
-
Norma NOMPaquetes: Se aceptan
números en le nombre de los paquetes.
-
Norma ADIdentificador. Se modifica para
incluir una excepción en el caso de tablas
para relaciones de muchos a muchos.
-
Apartado 10 Herramientas: Actualizado
para comtemplar el uso del servicio SAVT
en lugar de la herramienta de validación
HVAL.
1.17
EntornoEjecucion: A partir de la versión
1.2.6 de ATLAS se realizan los
despliegues en Tomcat no en Weblogic.
También cambia la JDK.
8 de 198
08/05/2014
Framework Atlas
Normativa
Índice
1
INTRODUCCION ................................................................................................................................................. 12
1.1
1.2
AUDIENCIA OBJETIVO ............................................................................................................................... 12
CONOCIMIENTOS PREVIOS ...................................................................................................................... 13
2
DESCRIPCION ..................................................................................................................................................... 15
3
PORTAL PARA EL DESARROLLO DE APLICACIONES ........................................................................... 17
4
ENTORNO DE DESARROLLO ......................................................................................................................... 18
5
PROYECTOS, MODULOS Y ARQUETIPOS .................................................................................................. 20
5.1
5.2
5.3
5.4
6
MODULO WEB .............................................................................................................................................. 23
MODULO LIBRERÍA .................................................................................................................................... 24
MODULO SERVICIO WEB........................................................................................................................... 25
MODULO BATCH ......................................................................................................................................... 26
ARQUITECTURA ................................................................................................................................................ 26
6.1
CONSIDERACIONES GENERALES ............................................................................................................ 26
6.2
PRESENTACION ........................................................................................................................................... 28
6.2.1
PAGINAS JSF......................................................................................................................................... 30
6.2.1.1
6.2.1.2
6.2.1.3
6.2.1.4
6.2.1.5
6.2.1.6
6.2.1.7
6.2.1.7.1
6.2.1.7.2
6.2.1.7.3
6.2.1.7.4
6.2.1.8
6.2.1.9
6.2.1.10
6.2.2
6.2.2.1
6.2.2.2
6.2.2.3
6.2.3
6.2.3.1
6.2.3.2
6.2.3.3
6.2.3.4
6.2.3.5
Manejo de eventos ............................................................................................................................................... 33
Recuperación de parámetros ................................................................................................................................ 35
Validadores .......................................................................................................................................................... 37
Conversores ......................................................................................................................................................... 39
Internacionalización ............................................................................................................................................. 39
Estructura y decoración de la página.................................................................................................................... 41
Uso de javascript .................................................................................................................................................. 46
Uso de JQuery en páginas JSF ......................................................................................................................... 46
Uso del objeto JQuery ..................................................................................................................................... 47
Uso de ready en sustitución del evento onLoad............................................................................................... 47
Localización de elementos por Id .................................................................................................................... 47
Normas de estilo .................................................................................................................................................. 48
Interfaces ricas de usuario (RIA) ......................................................................................................................... 49
Ayuda contextual ............................................................................................................................................. 52
MANAGED BEANS .............................................................................................................................. 53
Manejo de excepciones ........................................................................................................................................ 57
Navegación .......................................................................................................................................................... 59
Inicialización de los Beans (@PostContruct) ....................................................................................................... 61
CONFIGURACIÓN DE JSF ................................................................................................................... 61
faces-config.xml ................................................................................................................................................... 61
faces-managed-beans.xml .................................................................................................................................... 62
faces-navigation.xml ............................................................................................................................................ 64
Archivos de configuración adicionales y web.xml ............................................................................................... 67
Anotaciones ......................................................................................................................................................... 67
6.2.4
USO DE LA SESIÓN ............................................................................................................................. 69
6.3
SERVICIOS DE NEGOCIO ........................................................................................................................... 70
6.3.1
FACHADA.............................................................................................................................................. 72
6.3.2
SERVICIOS ............................................................................................................................................ 76
6.3.3
INYECCION DE DEPENDENCIAS ...................................................................................................... 81
6.3.4
MANEJO DE EXCEPCIONES .............................................................................................................. 84
6.3.5
TRANSACCIONALIDAD ..................................................................................................................... 87
6.3.6
FICHEROS TEMPORALES................................................................................................................... 92
6.4
ACCESO A DATOS ....................................................................................................................................... 94
6.4.1
DATASOURCE Y SESIONES DE HIBERNATE ................................................................................. 97
6.4.2
CONFIGURACIÓN ................................................................................................................................ 98
6.4.2.1
6.4.2.2
6.4.2.3
6.4.3
6.4.3.1
enviroment.properties .......................................................................................................................................... 98
applicationContext-database.xml ......................................................................................................................... 98
applicationContext-dao.xml ............................................................................................................................... 100
ENTIDADES DE DOMINIO................................................................................................................ 102
Mapeo relacional................................................................................................................................................ 108
9 de 198
Framework Atlas
Normativa
6.4.3.2
6.4.4
6.4.4.1
6.4.4.2
6.4.4.3
Tipos de datos BLOB y CLOB (LOB) ............................................................................................................... 110
DATA ACCESS OBJECTS .................................................................................................................. 112
Ejecución de consultas ....................................................................................................................................... 122
Manejo de excepciones ...................................................................................................................................... 124
Transaccionalidad .............................................................................................................................................. 124
6.4.5
LLAMADA A PROCEDIMIENTOS ALMACENADOS .................................................................... 126
6.4.5.1 LLAMADA A PROCEDIMIENTOS ALMACENADOS MEDIANTE HIBERNATE UTILIZANDO
NAMED QUERIES .............................................................................................................................................. 126
6.4.5.2 LLAMADA A PROCEDIMIENTOS ALMACENADOS MEDIANTE CALLABLESTATEMENT . 127
6.4.6
CACHÉS EN HIBERNATE ................................................................................................................. 129
6.4.6.1
6.4.6.2
6.4.6.3
Las cachés de primer y segundo nivel ................................................................................................................ 129
Las cachés distribuidas....................................................................................................................................... 131
La caché de consultas ......................................................................................................................................... 132
7
CONFIGURACION ............................................................................................................................................ 133
8
SERVICIOS BASICOS ...................................................................................................................................... 138
8.1
8.2
8.3
8.4
9
SERVICIO DE AUTENTICACION Y AUTORIZACION ........................................................................... 138
COMPONENTES DE PRESENTACION ..................................................................................................... 143
SERVICIO DE TRAZAS .............................................................................................................................. 144
SERVICIO DE AUDITORIA DE SEGURIDAD .......................................................................................... 146
INTEGRACION .................................................................................................................................................. 147
9.1
SERVICIO DE GESTIÓN DOCUMENTAL ................................................................................................ 148
9.2
SERVICIO DE PLANIFICACION ............................................................................................................... 149
9.3
SERVICIO DE CRIPTOGRAFIA................................................................................................................. 150
9.4
SERVICIO DE BUSSINESS INTELLIGENT .............................................................................................. 151
9.5
SERVICIO DE INVOCACIÓN DE SERVICIOS WEB ............................................................................... 153
9.6
SERVICIO DE PROCESOS DE NEGOCIO ................................................................................................. 154
9.7
OTRAS SOLUCIONES ................................................................................................................................ 155
9.7.1
REPORTING ........................................................................................................................................ 156
9.7.2
COMPOSICION DE DOCUMENTOS................................................................................................. 158
9.7.3
GESTION DE DOCUMENTOS EXCEL ............................................................................................. 160
9.7.4
GESTION DE DOCUMENTOS PDF ................................................................................................... 161
9.7.5
GENERACION DE GRAFICOS .......................................................................................................... 162
9.7.6
MANIPULACION DE ARCHIVOS MULTIMEDIA .......................................................................... 163
9.7.7
ACCESO A PLATAFORMA Y DISPOSITIVOS LOCALES ............................................................. 164
9.7.8
XML SÓLO LECTURA ....................................................................................................................... 165
9.7.9
XML LECTURA Y ESCRITURA ........................................................................................................ 165
9.7.10 ENVIO DE CORREO ........................................................................................................................... 168
9.7.11 ENVIO DE SMS ................................................................................................................................... 172
9.7.12 VISOR DE MAPAS .............................................................................................................................. 173
9.7.13 SERVICIOS WEB ................................................................................................................................ 174
10
HERRAMIENTAS .......................................................................................................................................... 175
10.1 VALIDACION DE NORMATIVA............................................................................................................... 175
10.2 REVISION DE CODIGO ESTATICO .......................................................................................................... 176
10.3 GENERACION AUTOMÁTICA DE CODIGO ........................................................................................... 178
10.3.1 ACCESO A DATOS ............................................................................................................................. 180
10.3.2 SERVICIOS DE NEGOCIO ................................................................................................................. 181
10.3.3 PRESENTACION ................................................................................................................................. 182
11
11.1
11.2
11.3
PRUEBAS ........................................................................................................................................................ 185
TIPOS DE PRUEBAS ................................................................................................................................... 185
PLAN DE PRUEBAS.................................................................................................................................... 190
DOCUMENTACION DEL CODIGO ........................................................................................................... 191
12
ENTREGA ....................................................................................................................................................... 192
13
ENLACES RELACIONADOS ...................................................................................................................... 193
A1.1
NORMAS ..................................................................................................................................................... 194
10 de 198
Framework Atlas
Normativa
A1.2
BUENAS PRACTICAS .............................................................................................................................. 198
11 de 198
Framework Atlas
Normativa
1
INTRODUCCION
La presente guía presenta el framework de desarrollo para todas las aplicaciones de la Comunidad de
Madrid y establece la normativa a cumplir en estos desarrollos. El framework se ha denominado Atlas y los
desarrollos deben cumplirlo en su última versión públicada.
En esta normativa se incluyen dos tipos de indicaciones para el correcto desarrollo de aplicaciones:
Normas: Son requisitos de obligado cumplimiento, y se encuentran definidas dentro de una caja
o
NORMA
de color azul:
NombreDeNorma
Contenido de la norma.
Buenas prácticas: Son recomendaciones para el desarrollo. No son de obligado cumplimiento
o
aunque para un correcto funcionamiento se recomienda cumplirlas siempre que sea posible. Se
1.1
PRACTICA
BUENA
encuentran definidas dentro de una caja de color
NombreDeBuenaPractica
Contenido de la Buena Práctica.
AUDIENCIA OBJETIVO
Este documento va dirigido a jefes de proyecto, analistas y desarrolladores de proyectos que utilicen el
framework Atlas.
12 de 198
Framework Atlas
Normativa
1.2
CONOCIMIENTOS PREVIOS
Para un completo entendimiento del documento, el lector deberá tener conocimientos previos sobre las
tecnologías que forman parte del framework.
A continuación se muestra una tabla con las distintas tecnologías utilizadas por cada uno de los elementos
del framework.
Servicio
Entorno de Desarrollo
Arquetipos
Arquitectura
Servicios Básicos
Integración
Tecnología
Respositorio maven
Artifactory
Gestión del proyecto
Maven
IDE de desarrollo
Eclipse
Servidor de Aplicaciones
Antes de ATLAS 1.2.6:
- Oracle Weblogic 10.3.3
A partir de ATLAS 1.2.6:
- Apache Tomcat 7.0.39
Motor de base de datos
Oracle
Control de versiones
Subversión
Integración continua
Cruise Control
Maquina virtual java
Antes de ATLAS 1.2.6:
- JRockit JDK 1.6.0_20
A partir de ATLAS 1.2.6:
- Oracle JDK 1.6.0_29
Generación de nuevos proyectos
Maven y Eclipse
Presentación
JSF, RichFaces, Ajax4JSF,
Facelets
Servicios
Spring
Acceso a Datos
Hibernate
Servicios Web
Axis 2
Servicio de Autenticación y
Autorización
Spring Security
Componentes de Presentación
JSF, RichFaces, Ajax4JSF,
Facelets
Servicio de Trazas
Spring AOP y Log4J
Servicio de Auditoria
Spring AOP e Hibernate
Servicio de Gestión Documental
Documentum 6.0
Servicio de Planificación
Control M
Servicio de ASF
ASF 3.5
13 de 198
Framework Atlas
Normativa
Otras soluciones
Herramientas
Servicio de Bussiness Inteligent
SAP Bussiness Objects XI 3.1
Servicio de Invocación de
Servicios Web
Axis 1.4
Servicio de Procesos de Negocio
Oracle BPM 10
Documentos PDF
IText
Reporting
Crystal Reports 2008
Composición de documentos
Velocity
Documentos Excel
Apache POI
Generación de Gráficos
JFreechart
Archivos multimedia
Java Media FrameWork API
(JMF)
Acceso a dispositivos locales
Applet
XML
Jaxb
Envío de correo
Java Mail
Envio de SMS
Servicio web mentes_ws
Monitorización
JMS y JMX
Pruebas de carga
JMeter
Pruebas de aceptación
Selenium
Pruebas unitarias
JUnit
Validación normativa
Maven
Validación estática de código
Checkstyle y PMD
14 de 198
Framework Atlas
Normativa
2
DESCRIPCION
El framework Atlas es un conjunto de componentes de software para simplificar el desarrollo de las
aplicaciones, ya que implementan aquellos requisitos que son compartidos por muchas de ellas.
Otra parte del framework es la normativa que garantiza la homogeneidad de los desarrollos y vela por
conseguir un código de calidad.
A continuación se muestra una imagen que contiene los distintos elementos del framework.
o
Entorno de desarrollo: Herramientas necesarias para el desarrollo de aplicaciones con el
framework Atlas
o
Arquitectura: Son los pilares que constituyen la base fundamental del Framework (JSF, Spring e
Hibernate)
o
Servicios Básicos: Servicios de uso común en la mayoría de los aplicaciones
15 de 198
Framework Atlas
Normativa
o
Arquetipos: Generadores de nuevos proyectos con la estructura básica de un proyecto Atlas
(plantillas de partida para el arranque de nuevos proyectos).
o
Integración: Integración con otras tecnologías como Documentum, BPM, etc
o
Herramientas: Utilidades de testing, validación y monitorización de aplicaciones.
o
Normativa: Normativa de obligado cumplimiento para el desarrollo de aplicaciones con el
framework.
16 de 198
Framework Atlas
Normativa
3
PORTAL PARA EL DESARROLLO DE APLICACIONES
Toda la documentación y recursos del framework Atlas se encuentra accesible en el portal para el
desarrollo de aplicaciones de la Unidad de Arquitectura y Soporte de Aplicaciones en la url:
http://gestiona.madrid.org/arquitecturasw.
Esta web es el canal de comunicación de la Unidad de Arquitectura y Soporte de Aplicaciones hacia los
proveedores.
Cada vez que se publica algo en la web se incluye una noticia indicando la actualización que se ha
realizado. El proveedor por lo tanto tiene la responsabilidad de conectarse asiduamente a esta web para
estar al corriente de las modificaciones.
Las consultas relacionadas con el desarrollo de aplicaciones se deben dirigir a la Unidad de Arquitectura y
Soporte de Aplicaciones a través del portal para el desarrollo en el apartado “Contactar con Arquitectura”
en la página de Inicio.
17 de 198
Framework Atlas
Normativa
4
ENTORNO DE DESARROLLO
Las siguientes imagenes muestran los elementos a grandes rasgos
Entorno Desarrollo Proveedor
Eclipse + plugin Maven (+ plugin subversion)
Maven
Base de Datos
(Oracle)
Repositorio
Local
Servidor de
Aplicaciones
(WebLogic)
Entorno ICM
Artifactory
Arquetipos
Portal para el
desarrollo
web
jar
Subversion
batch
service
Artefactos
docum
CruiseControl
Oracle
Weblogic
En el manual ATLAS_MUS_Preparacion_Entorno_Desarrollo detallan los productos y versiones de los
mismos que son necesarios para el desarrollo de aplicaciones con el framework Atlas. Por otra parte se
indica como preparar el entorno para comenzar a desarrollar aplicaciones.
18 de 198
Framework Atlas
Normativa
Entorno
El proveedor deberá replicar en sus instalaciones el entorno de desarrollo de ICM en cuanto a
productos y versiones de los mismos.
Las aplicaciones deberán desarrollarse teniendo en cuenta los siguientes aspectos relativos al
entorno:
·
En el entorno de producción podrán ser desplegadas en modo cluster, tanto en varias
instancias de un mismo o diferentes servidores de aplicaciones.
NORMA
·
No deben usar funcionalidades o tecnologías dependientes del sistema operativo sin la
previa aprobación de ICM.
·
No deben usar funcionalidades propietarias del servidor de aplicaciones, sin la previa
aprobación de ICM, para garantizar al máximo la portabilidad entre servidores de
aplicaciones.
·
Los ficheros generados por las aplicaciones y que se necesiten dejar en disco se ubicarán
según se indique en un parámetro del fichero de configuración. Esta ubicación
corresponderá con un directorio compartido por las distintas maquinas que compongan el
cluster.
·
Las aplicaciones web y servicios web se van a ejecutar en varias maquinas virtuales por
lo tanto los objetos que se dejen en la memoria de la maquina virtual no estarán
replicados en las diferentes instancias.
EntornoEjecucion
NORMA
Las aplicaciones Atlas anteriores a la versión 1.2.6 se desplegarán en el servidor de
aplicaciones Oracle Weblogic 10.3.3 y se ejecutarán con la JDK JRockit 1.6.0_20.
A partir de la versión 1.2.6 se desplegarán en el servidor de aplicaciones Apache Tomcat
7.0.39 y se ejecutarán con la JDK Oracle 1.6.0_29.
El codigo entregado deberá estar probado con esta versión de JDK y funcionar correctamente en
este servidor de aplicaciones.
19 de 198
Framework Atlas
Normativa
5
PROYECTOS, MODULOS y ARQUETIPOS
Las aplicaciones de la Comunidad de Madrid se definirán en el marco de un proyecto, denominando a las
distintas aplicaciones que se desarrollen para un proyecto módulos. Por lo tanto podemos decir que un
proyecto es un conjunto de módulos.
Todos los proyectos de la Comunidad de Madrid tienen un nombre como máximo de 4 letras que
identifican al proyecto y que van a ser fundamentales en la nomenclatura de muchos de los elementos
del proyecto por lo tanto es fundamental disponer de este identificador antes de abordar ningún tipo de
desarrollo.
A continuación se muestra la estructura de carpetas sobre como se debe crear un proyecto y sus
correspondientes módulos.
PROYECTO
XXXX
MODULOS
XXXX_MODD
BASE DATOS
XXXX_APP
APP WEB
XXXX_WS
SERVICIO WEB
XXXX_BATCH
XXXX_LIB
BATCH
LIBRERIA
Atención
xxxx se corresponde con el nombre del proyecto y como podemos ver este nombre forma parte del
nombre de los módulos.
20 de 198
Framework Atlas
Normativa
Observar que el separador utilizado en el nombre de los módulos es el guión bajo.
Dentro de los módulos de un proyecto nos podemos encontrar con módulos del framework Atlas o con otro
tipo de módulos (por ejemplo un módulo de Documentum, un módulo de base de datos, etc).
Los distintos tipos de módulos que podemos implementar con el framework Atlas son:
o
Módulo web: Para implementar aplicaciones de tipo web.
o
Módulo librería: Para implementar librerías (jars).
o
Módulo servicio web: Para implementar servicios web.
o
Módulo batch: Para implementar aplicaciones o procesos que se ejecutarán en modo batch.
Los arquetipos son plantillas de proyectos Maven que se utilizarán como punto de partida de cualquier
módulo desarrollado con el framework Atlas. Antes de crear ningún módulo debemos crear el propio
proyecto, partiendo de un arquetipo de proyecto que crea la estructura necesaria.
NORMA
Arquetipos
Todo proyecto debe partir obligatoriamente de un arquetipo de tipo proyecto (atlasfrmarquetipos-generador-proyecto).
El desarrollo de cualquier módulo de un proyecto serán submódulos de éste, que obligatoriamente
se deben hacer partiendo del arquetipo correspondiente al módulo en cuestión.
Actualmente se dispone de los siguientes arquetipos dentro del framework Atlas:
ARQUETIPOS
DESCRIPCION
atlasfrm-arquetipos-
Genera un proyecto base de partida
generador-proyecto
para cualquier aplicación de ATLAS.
Tipo de módulo
Proyecto de inicio
Cualquiera de los módulos del
proyecto deberán ser submódulos
de éste.
atlasfrm-arquetipos-
Genera un proyecto Maven
generador-web
preparado para el desarrollo de
módulos web con JSF, Spring e
Hibernate.
21 de 198
Módulo web
Framework Atlas
Normativa
atlasfrm-arquetipos-
Genera un proyecto Maven de tipo
generador-servicioweb
web listo para desplegar un servicio
Módulo servicio web
web con Axis2, Spring e Hibernate
atlasfrm-arquetipos-
Genera un proyecto Maven de tipo
generador-documentumweb
web listo para ser utilizado con
Módulo web
aplicaciones que se integren con
Documentum
atlasfrm-arquetipos-
Genera un proyecto Maven
generador-batch
preparado para el desarrollo de
Módulo batch
módulos de tipo batch, con sus
scripts de ejecución preparada para
distribución. Contiene
configuraciones de Spring e
Hibernate
atlasfrm-arquetipos-
Genera un proyecto Maven
generador-jar
preparado para el desarrollo de
Módulo librería
módulos de tipo librería (jar).
NORMA
NORMA
NOMArchivo
Los nombres de los archivos sólo pueden estar formados por caracteres [a-z] y guiones medio y
bajo, no pudiéndose utilizar caracteres acentuados ni la letra eñe. En los nombres de los archivos
pueden utilizarse letras mayúsculas cuando sea conveniente.
NOMPaquetes
Los nombres de los paquetes de clases Java sólo pueden estar formados por caracteres [a-z] en
minúscula y dígitos [0-9], no pudiéndose utilizar caracteres acentuados ni la letra eñe.
NORMA
VERSIONADO
Todos los proyectos deben versionarse utilizando los mecanismos de versionado que ofrece
Maven, utilizando la etiqueta <version> que se encuentra dentro del fichero pom.xml.
Siempre que se realicen modificaciones sobre un módulo y se proceda a una entrega (en
cualquier entorno) se ha de modificar el número de versión.
El número de versión estará formado por tres digitos. Ejemplo 1.0.3
22 de 198
Framework Atlas
Normativa
5.1
MODULO WEB
Para el desarrollo de módulos web el framework Atlas incluye un arquetipo web que se deberá utilizar
para la implementación del mismo.
Para obtener más información sobre el arquetipo web consultar el manual ATLAS_MUS_Arquetipo_Web.
IMPLWEB
Para implementar un módulo/aplicación web se creará un módulo partiendo del arquetipo web y
NORMA
con la siguiente nomenclatura:
xxxx_yyyy
donde
xxxx se corresponde con el nombre del proyecto (max 4 caracteres)
yyyy se corresponde con el nombre descriptivo del web (No se puede poner en este
nombre el sufijo “web” ya que se la va a incluir automáticamente al generar el módulo
desde el arquetipo)
23 de 198
Framework Atlas
Normativa
5.2
MODULO LIBRERÍA
En algunos proyectos nos encontramos con que determinadas código debe de estar compartido por varios
módulos del proyecto, en ese caso es necesario crear un nuevo módulo de tipo librería cuya dependencia
NORMA
será incluida en cada uno de los módulos que lo necesite.
LIBCOMUN
Cuando varios módulos de una o varias aplicaciones tengan código en común, ya sean métodos o
clases, se deberá crear una librería de clases que servirá para compartir el código común anterior.
Para el desarrollo de módulos librería el framework Atlas incluye un arquetipo jar que se deberá utilizar
para la implementación del mismo.
Para obtener más información sobre el arquetipo jar consultar el manual ATLAS_MUS_Arquetipo_Jar.
IMPLLIB
Para implementar un módulo librería se creará un módulo partiendo del arquetipo jar y con la
NORMA
siguiente nomenclatura:
xxxx_lib_<yyyy>
donde
xxxx se corresponde con el nombre del proyecto (max 4 caracteres)
yyyy se corresponde con el nombre descriptivo de la librería (Este nombre es opcional y
debe distinguir a una librería de otra)
24 de 198
Framework Atlas
Normativa
5.3
MODULO SERVICIO WEB
Si existe la necesidad de que determinada funcionalidad de nuestra aplicación sea expuesta como un
servicio web a otras aplicaciones se deberá crear un módulo específico que implemente el servicio web.
El framework Atlas incluye un arquetipo de servicio web que se deberá utilizar para la implementación
del mismo. Para obtener más información sobre el arquetipo de servicio web consultar el manual
ATLAS_MUS_Arquetipo_Servicio_Web.
IMPLWS
Para implementar un servicio web se creará un módulo partiendo del arquetipo servicio web y con
NORMA
la siguiente nomenclatura:
xxxx_ws_<yyyy>
donde
xxxx se corresponde con el nombre del proyecto (max 4 caracteres)
yyyy se corresponde con el nombre descriptivo del servicio web (Este nombre es opcional
y debe distinguir a un servicio web de otro)
Para facilitar la integración de las aplicaciones clientes con este tipo de módulos es necesario
proporcionales una librería cliente que permita invocar a los métodos publicados en el servicio web. Por lo
tanto todos los módulos de tipo servicio web llevarán incluido un submódulo con la parte cliente necesaria
para invocarlos. Este submódulo ya se encuentra en el arquetipo de servicio web.
WSLibCliente
Cada módulo de tipo servicio web debe incluir su correspondiente librería cliente que será un
NORMA
submódulo de tipo librería con la siguiente nomenclatura:
xxxx_ws_<yyyy>_lib
donde
xxxx se corresponde con el nombre del proyecto (max 4 caracteres)
yyyy se corresponde con el nombre descriptivo del servicio web (Este nombre es opcional
y debe distinguir a un servicio web de otro)
25 de 198
Framework Atlas
Normativa
5.4
MODULO BATCH
Si existe la necesidad de que determinada funcionalidad de nuestra aplicación sea ejecute en modo batch
se creará un módulo de tipo batch.
El framework Atlas incluye un arquetipo de aplicaciones batch que se deberá utilizar para la
implementación del mismo. Para obtener más información sobre el arquetipo de batch consultar el manual
ATLAS_MUS_Arquetipo_Batch.
IMPLBatch
Para implementar un batch se creará un módulo partiendo del arquetipo batch y con la siguiente
nomenclatura:
NORMA
xxxx_batch_<yyyy>
donde
xxxx se corresponde con el nombre del proyecto (max 4 caracteres)
yyyy se corresponde con el nombre descriptivo del batch (Este nombre es opcional y debe
distinguir a un programa batch de otro)
6
ARQUITECTURA
El framework Atlas está basado fundamentalmente en tres tecnologías: JSF, Spring e Hibernate, que dan
soporte a la implementación de las distintas capas de la aplicación:
·
Presentación: Java Server Faces (JSF)
·
Servicios: Spring
·
Acceso a datos: Hibernate
Es fundamental el conocimiento por parte del desarrollador de estas tres tecnologías para poder llevar a
cabo con exito el desarrollo de una aplicación con el framework Atlas.
6.1
CONSIDERACIONES GENERALES
A continuación se exponen una serie de normas que son de carácter general para el código Java a
desarrollar.
26 de 198
Framework Atlas
NORMA
REFLEXION
NORMA
GARBAGE
NORMA
MULTIHILO
NORMA
Normativa
CLASESIGUALES
No está permitido el uso de la Reflectividad (bien sea para buscar e invocar métodos o bien para
acceder a atributos de una clase), a no ser que sea previamente autorizada por ICM.
No está permitida la invocación directa al garbage collector mediante System.gc(), a no ser que
tras consultarlo sea autorizada por ICM.
En aplicaciones web o servicios web no pueden utilizarse hilos (threads) de ejecución distintos del
hilo principal, a no ser que sea previamente autorizado por ICM.
No puede haber dos clases que se llamen igual aunque estén en dos paquetes distintos.
27 de 198
Framework Atlas
Normativa
6.2
PRESENTACION
La lógica de presentación de la aplicación abarca todos los aspectos relacionados con la presentación de
información al usuario final.
La arquitectura de Atlas se basa principalmente en el uso de la tecnología Java Server Faces (JSF) para la
creación de la lógica de presentación de la aplicación, si bien hay ciertas funcionalidades que son
responsabilidad de esta capa y que emplean algún framework o producto adicionales.
No obstante para ciertas tipologías de aplicaciones (aplicaciones meramente informativas, esto es,
aquellas cuyo principal objetivo es mostrar información al usuario final) el uso de esta tecnología complica
la integración con la infraestructura actual de ICM. Tal es el caso de las aplicaciones o sitios Web que
dependen de “madrid.org” implementados mediante las herramientas que ofrece el gestor de contenidos
corporativo de ICM (Fatwire). Este tipo de aplicaciones están fuera del alcance del presente documento,
las cuales están sujetas a una normativa propia.
La arquitectura de componentes que proporciona JSF, incluye:
·
·
Un API para representar componentes de interfaz de usuario y gestionar:
o
Su estado.
o
Los eventos generados por la interfaz.
o
La validación y conversión de datos en el lado del servidor.
o
La definición de las reglas de navegación entre páginas.
o
Los aspectos relacionados con internacionalización y accesibilidad.
o
Los puntos de extensión para todas estas características.
Librerías de etiquetas personalizadas para implementar la interfaz de las Java Server Faces y
para asociar los componentes a los objetos del lado del servidor.
Desde el punto de vista del desarrollo, una aplicación JSF es como cualquier otra aplicación web Java.
Típicamente, una aplicación JSF incluye las siguientes piezas principales:
·
Un conjunto de páginas xhtml, que usarán etiquetas especiales definidas por la especificación JSF.
·
Un conjunto de managed beans, que no son más que JavaBeans que definen propiedades y
funciones para los componentes de interfaz de usuario de las páginas.
·
Archivos de configuración para la aplicación, que definen las reglas de navegación y configuran los
beans y los componentes a medida.
·
Un descriptor de despliegue (el fichero “web.xml” de toda aplicación web).
·
Los componentes y objetos a medida creados por el desarrollador para ampliar el modelo estándar
(nuevos componentes visuales, validadores, conversores, etc.).
28 de 198
Framework Atlas
Normativa
La siguiente figura muestra el modelo de componentes que propone JSF, además se resumen las
principales funcionalidades aportadas por dicha tecnología y que se encuentran incluidas en el presente
documento.
Funcionalidades
Componentes de IU
Integración con modelo de objetos
Gestión de contexto de usuario
Modelo de “renderizado”
Manejo de eventos en el servidor
Conversión de tipos y validación
Navegación
Internacionalización
Modelo
Managed Beans
Vista
Controlador
Componentes UI
FacesServlet
Una de las mayores ventajas de JSF es que ofrece una clara separación entre presentación y
comportamiento. JSF permite hacer un mapeo de las peticiones HTTP a elementos específicos para el
manejo de eventos además de manejar los elementos de interfaz de usuario como si fueran objetos con
estado en el lado del servidor. Otra ventaja importante de la tecnología JSF es que permite utilizar los
componentes de interfaz de usuario sobre cualquier otra tecnología de presentación para otro tipo de
dispositivos. Y lo más importante, JSF aporta una arquitectura para manejar el estado de los componentes,
el proceso de los datos, la validación de las entradas del usuario y el manejo de eventos.
El uso de JSF aporta las siguientes ventajas adicionales:
·
Es un estándar JEE. Esto asegura que los principales fabricantes de servidores de aplicaciones e
IDEs sean compatibles con JSF.
·
Al ser un modelo basado en componentes, la productividad es mayor y se fomenta la reutilización.
·
Posibilita el uso de herramientas de diseño visuales.
·
Ofrece una separación nítida entre presentación y lógica de negocio, y por tanto, de los roles
involucrados.
·
Flexibilidad. Permite a los desarrolladores la ampliación de los componentes de las librerías de
etiquetas e incluso la creación de otros nuevos.
·
Apta para la gestión de clientes heterogéneos (WML, Wap, HTML, XML, etc.).
En la actualidad existen un extenso conjunto de librerías de componentes JSF, tanto comerciales como de
código abierto. Para el desarrollo de aplicaciones Atlas pueden utilizarse alguna de ellas.
NORMA
JSFComponentes
Para la implementación de la interfaz de usuario de las aplicaciones con JSF, sólo se podrán
emplear los componentes propios de Atlas, los de MyFaces, RichFaces y sus extensiones.
Las librerías para estos componentes ya se encuentran dentro del repositorio Maven de ICM.
29 de 198
Framework Atlas
Normativa
6.2.1
PAGINAS JSF
En las páginas JSF se situan los distintos elementos que formaran las páginas a mostrar al usuario final de
la aplicación.
JSFXHTML
Todos los ficheros JSF deberán ser documentos XHTML con extensión “.xhtml”.
NORMA
Como sistema de codificación se empleará UTF-8. Los componentes Web transmitirán todas las
páginas con dicho sistema de codificación (encoding="UTF-8").
Todas las páginas JSF se ubicarán en la carpeta src/main/webapp y subcarpetas.
Para distinguir aquellas páginas cuyo acceso esté securizado estas se ubicarán en una carpeta
llamada src/main/webapp/secure. Dentro de esta carpeta se podrán crear las subcarpetas
necesarias para poder llevar una gestión de perfiles de acceso.
JSFPOB
NORMA
Las páginas deben de ser compatibles con las versiones de Navegador Internet Explorer 7 o
superior, Mozilla Firefox 3.6.28 o superior, y Google Chrome 31 o superior.
Los módulos que se desarrollen para los usuarios de la Intranet deben funcionar correctamente
con el POB (Puesto ofimático básico) que tienen instalado en su PC.
A continuación se muestra un ejemplo de página JSF:
Ejemplo de página JSF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:atlas="http://atlas.core.componentes/jsf"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
>
<ui:composition template="/WEB-INF/layout/vc.xhtml">
30 de 198
Framework Atlas
Normativa
<ui:define name="rastroMigas">
<ui:include src="/secure/rastroMigas/rastro.xhtml" />
</ui:define>
<ui:define name="menuVertical">
<ui:include src="/secure/menu/menu.xhtml" />
</ui:define>
<ui:define name="content">
<h:form id="mainPanel">
<atlas:guardarEstado id="stateIdCliente"
value="#{clientesBean.cliente}" />
<h:panelGroup>
<h:panelGrid width="70%" columns="3">
<h:outputLabel id="outputLabelNombre"
for="inputTextNombre"
styleClass="label"
value="#{bundle['inputText.nombre']}" />
<h:panelGroup>
<h:inputText id="inputTextNombre"
size="50" maxlength="50"
styleClass="cajaTextoObligat"
value="#{clientesBean.cliente.nombre}"
required="true" />
</h:panelGroup>
<h:panelGroup>
<h:message for="inputTextNombre"
styleClass="mensajeERRORtxt"
showDetail="true" showSummary="false" />
</h:panelGroup>
<h:outputLabel id="outputLabelApellido1"
for="inputTextApellido1"
styleClass="label"
value="#{bundle['inputText.apellido1']}" />
<h:panelGroup>
<h:inputText id="inputTextApellido1" size="50" maxlength="50"
styleClass="cajaTextoObligat"
value="#{clientesBean.cliente.apellido1}"
required="true">
</h:inputText>
</h:panelGroup>
<h:panelGroup>
<h:message for="inputTextApellido1"
styleClass="mensajeERRORtxt"
showDetail="true" showSummary="false"/>
</h:panelGroup>
...
<h:outputText styleClass="botonAplicacionTXT"
value="#{bundle['boton.vuelta_atras']} " />
<h:graphicImage value="img/portal/filtro.jpg"
alt="#{bundle['boton.vuelta_atras']}" />
</h:commandLink>
<h:commandLink id="guardarLink"
action="#{clientesBean.guardarCliente}"
styleClass="buttonsRowLeftColumn">
<h:outputText styleClass="botonAplicacionTXT"
value="#{bundle['boton.guardar_cliente']} " />
<h:graphicImage value="img/portal/filtro.jpg"
alt="#{bundle['boton.guardar_cliente']}" />
</h:commandLink>
...
</ui:composition>
31 de 198
Framework Atlas
Normativa
</html>
El acceso a la capa de negocio desde las páginas JSF se hará a través de clases java llamadas managed
beans o beans de respaldo.
La asociación de datos entre los componentes de las páginas y sus managed beans se puede hacer de
dos maneras:
·
Asociación de valores: permite configurar una propiedad de un componente de la página mediante
un atributo de un bean.
Ejemplo de asociación de valores
<h:inputText id="inputTextNombre" size="50"
maxlength="50"
styleClass="cajaTextoObligat"
value="#{clientesBean.cliente.nombre}"
required="true" />
·
Asociación a métodos: permite configurar una propiedad de un componente de la página con el
resultado de la invocación a un método del bean.
Ejemplo de asociación a métodos
<h:commandLink id="guardarLink"
action="#{clientesBean.guardarCliente}"
styleClass="buttonsRowLeftColumn">
<h:outputText styleClass="botonAplicacionTXT"
value="#{bundle['boton.guardar_cliente']}" />
<h:graphicImage value="img/portal/filtro.jpg"
alt="#{bundle['boton.guardar_cliente']}" />
</h:commandLink>
PRACTICA
Se recomienda que desde cada página JSF solamente se acceda a un único managed bean
que ofrecerá la interfaz necesaria para la invocación de esa página, salvo en el caso de varias
páginas que gestionen el mismo tipo de invocaciones.
JSFGet
CA
PRACTI
BUENA
BUENA
JSFManagedBean
En la asociación de valores, JSF llama al método get correspondiente del bean para obtener el
valor. Se recomienda no poner lógica en estos métodos, ya que pueden ser llamados un
32 de 198
Framework Atlas
Normativa
número elevado de veces durante el ciclo de vida de una petición. En caso de que el valor a
devolver deba calcularse u obtenerse de base de datos debería hacerse en otro método que se
ejecute sólo una vez (constructor de la clase, método action del componente que desencadene
la acción…).
JSFNegocio
NORMA
Desde las páginas JSF solamente se podrá acceder a managed beans.
No está permitido la invocación a los objetos de acceso a datos (DAOs) de la aplicación ni objetos
de servicio de negocio.
PRACTICA
BUENA
Tampoco está permitido el uso de código Java directamente en la página JSF.
JSFTamano
Las páginas JSF se deberán diseñar y modularizar de tal forma que no tomen unas
dimensiones excesivas.
PRACTICA
BUENA
JSFEL
6.2.1.1
Se recomienda no utilizar expresiones EL excesivamente complejas en las páginas XHTML,
para esos casos es preferible codificar la expresión en una propiedad del managed bean y
hacer referencia a dicha propiedad.
Manejo de eventos
El manejo de eventos debe realizarse mediante acciones siempre que sea posible. En el atributo action se
debe indicar el método JSF que será invocado ante el click de un usuario en los elementos commandLink,
commandButton o cualquier componente que herede dicho comportamiento. Este método debe ser
público, sin parámetros y retornar un String con la dirección que tomarán las reglas de navegación:
En la página JSF
<h:commandLink id="guardarLink"
action="#{clientesBean.guardarCliente}"
styleClass="buttonsRowLeftColumn">
<h:outputText styleClass="botonAplicacionTXT"
value="#{bundle['boton.guardar_cliente']} " />
33 de 198
Framework Atlas
Normativa
<h:graphicImage value="img/portal/filtro.jpg"
alt="#{bundle['boton.guardar_cliente']}" />
</h:commandLink>
En el managed bean
/**
* Este metodo inserta o modifica un cliente en el sistema.
*
* @throws atlas.core.exceptions.ServiceException
*
Lanza atlas.core.exceptions.ServiceException ante cualquier error
* @return <code>java.lang.String</code> Devuelve la regla de navegacion
* <code>NavigationResults.VOLVER_LISTADO_CLIENTES</code>.
*/
public String guardarCliente() throws ServiceException {
try {
facade.insertOrUpdateCliente(cliente);
} catch (ServiceException se) {
AtlasFacesUtils.storeOnRequestError(FacesContext.getCurrentInstance(),
"error.CLIENTES_MODIFICAR", se);
throw se;
}
return NavigationResults.VOLVER_LISTADO_CLIENTES;
}
Para más información sobre el uso de NavigationResults ver el apartado de Managed Beans.
En caso de existir la necesidad de acceder a elementos de la interfaz de usuario durante la ejecución se
puede capturar la llamada mediante un actionListener, esto permite recibir información sobre el estado de
los componentes visuales del cliente mediante el parámetro que es enviado:
En la JSF
<h:commandLink action="#{miBean.accion}"
actionListener="#{miBean.escuchadorAccion}">
<h:outputText value="#{bundle['texto_del_link']}"/>
</h:commandLink>
En el managed bean: accion
public String accion() {
//Lógica de la accion.
return NavigationResults.MOSTRAR_RESULTADO;
}
En el managed bean: escuchadorAccion
public void escuchadorAccion(ActionEvent evento) {
34 de 198
Framework Atlas
Normativa
//Lógica relacionada con los componentes UI del cliente por ejemplo,
//recuperar los hijos y facets del componente:
evento.getComponent().getFacetsAndChildren();
}
JSFAcciones
Como norma general, se empleará el manejo de eventos mediante acciones (en lugar de
PRACTICA
BUENA
ActionListeners) si bien se deberá elegir con cuidado que alternativa de las dos será la óptima
en cada caso.
En el caso de manejo de eventos mediante actionListeners se recomienda que se realice en
conjunción con acciones estándar, incluyendo la lógica de control de aplicación en estas últimas
y delegando sólo las tareas relacionadas con manejo avanzado de los componentes de usuario
a los actionListeners.
Por otro lado, están los escuchadores de propiedades (ValueChangeListener) que permiten ejecutar
métodos de un managed bean cuando cambia una propiedad de un componente de interfaz de usuario:
En la página JSF
<h:selectBooleanCheckbox id="changeColorMode"
valueChangeListener="#{resumeBean.changeColorMode}"
immediate="true"
onchange="submit()" />
En el managed bean
public void changeColorMode(ValueChangeEvent event) {
boolean flag = ((Boolean) event.getNewValue()).booleanValue();
setUsingColorNames(!flag);
}
6.2.1.2
Recuperación de parámetros
Como norma general no será necesario enviar parámetros adicionales ya que JSF se encargará de realizar
llamadas a los métodos set de los atributos que representan los campos de un formulario, pero habrá
casos en los que será necesario el envío de información adicional. Un claro ejemplo es el caso de una
funcionalidad maestro-detalle donde se debe enviar un elemento de un listado para poder mostrar
posteriormente el detalle del mismo.
Para ello disponemos de dos mecanismos:
o
f:setPropertyActionListener
35 de 198
Framework Atlas
Normativa
o
f:param
El primero consiste en el envío del objeto completo al realizar la acción. Anidando el componente
setPropertyActionListener dentro de un commandLink o un commandButton conseguimos que JSF
actualice los valores de propiedades e incluso objetos completos al realizar una acción:
Ejemplo de updateActionListener
<atlas:listaPaginada ..............>
<h:column .....>
<h:commandButton value="#{bundle['texto_del_boton']}"
action="#{miBean.mostrarCliente}">
<f:setPropertyActionListener value="#{item}"
target="#{miBean.cliente}"/>
</h:commandButton>
</h:column>
</atlas:listaPaginada>
En este ejemplo cuando se invoca el método mostrarCliente en el atributo cliente se establece el valor
‘item’.
Lamentablemente no siempre es posible hacer uso de esta estrategia, por ejemplo en acciones que tienen
el atributo immediate="true". Para estas situaciones disponemos de otro método que nos permite enviar
parámetros de tipos de dato primitivos (no objetos o arrays). Cualquier componente de tipo
commandButton, commandLink, outputLink o derivados de los mismos acepta componentes anidados de
tipo f:param, que envía el valor asociado a una clave como parámetro de la request. Al ser enviado como
parámetro de la request podemos recuperar dichos parámetros en cualquier punto del ciclo de vida de JSF,
incluso en el constructor del Managed Bean si fuese necesario:
En la JSF
<atlas:listaPaginada ..............>
<h:column .....>
<h:commandButton value="#{bundle['texto_del_boton']}"
action="#{miBean.mostrarCliente}">
<f:param value="#{item.idCliente}"
name ="parametroIdCliente"/>
</h:commandButton>
</h:column>
</atlas:listaPaginada>
En el managed bean
public String mostrarCliente() {
Long idCliente = (Long) FacesSupport.getParameter("parametroIdCliente");
//Cargamos el cliente a partir de su Id llamando a la fachada de
36 de 198
Framework Atlas
Normativa
//servicios
this.cliente = gestionFacade.cargarCliente(idCliente);
return NavigationResults.MOSTRAR_CLIENTE;
}
Mediante estas técnicas y el uso del componente atlas:guardarEstado que se explicará en detalle más
adelante podemos reducir al máximo el uso de la sesión.
6.2.1.3
Validadores
La arquitectura de JSF ofrece mecanismos para automatizar la validación de los datos de una aplicación.
Del mismo modo, ofrece la posibilidad de crear validadores a medida.
Las validaciones estándar de JSF se realizan en el servidor, aunque también es posible hacer validaciones
en el cliente (mediante javascript).
Los errores de validación se pueden mostrar mediante los mensajes de JSF utilizando <h:message/> o
<h:messages/>.
Ejemplo de uso de un validador standard
<h:inputText id="number1" value="#{calcFormBean.number1}" maxlength="2"
size="25" required="true">
<f:validateLongRange minimum="1" maximum="10" />
</h:inputText>
<h:message id="number1Error" for="form1:number1" styleClass="error" />
Esta validación comprueba que se haya introducido un valor numérico en el campo “number1”, y que su
longitud no supere los 2 caracteres. Además se comprueba que el número introducido esté entre el 1 y 10.
Si los datos introducidos son erróneos, se mostrará un mensaje de error.
También existen validadores estándar asociados a ciertos componentes de entrada de datos.
Ejemplo de campo obligatorio
<h:outputLabel id="outputLabelNombre" for="inputTextNombre"
styleClass="label" value="#{bundle['inputText.nombre']}" />
<h:panelGroup>
<h:inputText id="inputTextNombre" size="50" maxlength="50"
styleClass="cajaTextoObligat"
value="#{clientesBean.cliente.nombre}" required="true" />
</h:panelGroup>
<h:panelGroup>
<h:message for="inputTextNombre" styleClass="mensajeERRORtxt"
showDetail="true" showSummary="false" />
</h:panelGroup>
37 de 198
Framework Atlas
Normativa
En el ejemplo anterior hacemos uso de dicho componente para mostrar un error cuando el usuario no
introduzca nada en el campo “inputTextNombre”.
Si deseamos personalizar el mensaje de error a mostrar cuando se produzca un error de
PRACTICA
BUENA
JSFMessages
validación, es recomendable el uso del componente de JSF para mostrar mensajes
(<h:message/> o <h:messages/>).
Para añadir mensajes al contexto se recomienda utilizar los métodos creados a tal efecto en en
la clase atlas.componentes.utiles.AtlasFacesUtils.
JSF también permite realizar validaciones a nivel de aplicación. Este tipo de validaciones se consideran
validaciones de lógica de negocio. Básicamente, la validación a nivel de aplicación conlleva añadir código
extra a los métodos de los managed beans, que hacen comprobaciones adicionales sobre los datos
obtenidos.
Por ejemplo, en una aplicación que implemente un carrito de la compra, la validación a nivel de formulario
comprobaría si una cantidad introducida es válida (previa conversión de la cantidad a un objeto java
conocido), y la validación a nivel de aplicación podría validar si el usuario ha excedido su límite de crédito.
NORMA
JSFValidacion
Todas las validaciones sobre campos de un formulario se han de implementar en el servidor. Si se
desea realizar las validaciones en el cliente, deberá existir una comprobación idéntica en el lado
del servidor, ya sea mediante validación estándar de JSF o mediante validación a nivel de
aplicación.
38 de 198
Framework Atlas
Normativa
JSFCustomValidator
Cuando sea necesario realizar una validación genérica para la que Atlas no ofrezca un validador
estándar, se implementará uno a medida.
NORMA
Para crear un validador a medida se creará una clase Java que implemente la interfaz
Validator, con la siguiente nomenclatura:
o
<nombre>Validator
Donde nombre será sustituido por el nombre del validador.
Estas clases se incluirán en el paquete jsf.validators del bloque funcional correspondiente. En el
caso de que sean validadores genéricos para todo el proyecto se pueden ponen en un bloque
funcional común.
6.2.1.4
Conversores
Los datos procedentes de una petición Http son cadenas de caracteres. Por eso es necesario un
mecanismo de conversión de dichas cadenas al tipo de datos deseado (el declarado en el managed bean
vinculado al campo del formulario).
Ejemplo de uso de un conversor
<h:outputText value="#{user.dateOfBirth}">
<f:convertDateTime type="both" dateStyle="full" />
</h:outputText>
JSFCustomConversor
Cuando sea necesario realizar un conversor particular para la que Atlas no ofrezca un conversor
estándar, se implementará uno a medida.
NORMA
Para crear un conversor a medida se creará una clase Java que implemente la interfaz
Converter, con la siguiente nomenclatura:
o
<nombre>Converter
Donde nombre será sustituido por el nombre del conversor.
Estas clases se incluirán en el paquete jsf.converters del bloque funcional correspondiente. En el
caso de que sean conversores genéricos para todo el proyecto se pueden ponen en un bloque
funcional común.
6.2.1.5
Internacionalización
39 de 198
Framework Atlas
Normativa
El conjunto de elementos culturales, políticos y específicos de una región representados en una aplicación
se denominan “locale”. Las aplicaciones deberían personalizar la presentación de los datos en función del
“locale” preferido del usuario, de esta manera se puede definir el concepto de internacionalización
(También conocida como I18n) como el proceso de separar las dependencias “locale” del código fuente de
la aplicación. Ejemplos de dependencias “locale” pueden ser el conjunto de caracteres, encoding, moneda,
formato de tiempo, calendarios, etc.
El concepto de Localización (También conocido como L10n) es el proceso de adaptar una aplicación
internacionalizada a un “locale” específico, por lo que las aplicaciones tendrán que estar
internacionalizadas de forma previa a ser localizadas.
JSF dispone de un potente soporte a la internacionalización y la localización. Para desarrollar una
aplicación completamente internacionalizada, todos los literales incluyendo etiquetas, campos de fecha,
campos numéricos, campos de texto, mensajes de error y textos mostrados como alternativa a las
imágenes se han de externalizar a un archivo de propiedades. El entorno de ejecución de JSF determina el
“locale” de un usuario en base a la configuración de su navegador, aunque se puede establecer por
configuración el “locale” de la misma. JSF usa la clase ResourceBundle para cargar los mensajes de texto
del archivo de propiedades y mostrarlos en los componentes de presentación.
JSFInternalizacion
En las páginas JSF no puede haber literales de texto en un idioma específico.
Las aplicaciones contendrán un fichero para almacenar los mensajes internacionalizados. Este
NORMA
fichero se ubicará en la carpeta src/main/resources/msg, con la siguiente nomenclatura:
o
messages_xx.properties
Donde xx es el sufijo del locale al que corresponden los ficheros de mensajes.
Este fichero contendrá todos los mensajes de la aplicación.
El mecanismo de internacionalización no aplica a mensajes incluidos en trazas, al no ser
directamente visualizados por los usuarios finales.
Al menos se debe de entregar el fichero de mensajes del locale español (es).
Los distintos arquetipos ya vienen preparados con estos ficheros de mensajes y la configuración necesaria
para trabajar con ellos.
Desde la página JSF cuando queramos acceder a los textos del fichero de internacionalización se utilizará
el objeto bundle tal y como se muestra en el siguiente ejemplo:
40 de 198
Framework Atlas
Normativa
Ejemplo de uso de literales internacionalizados
PRACTICA
BUENA
<h:outputLabel id="outputLabelNombre" for="inputTextNombre"
styleClass="label"
value="#{bundle['inputText.nombre']}" />
6.2.1.6
JSFAccesoMessages
Para acceder a los elementos del fichero de mensajes se recomienda utilizar el método
getStringFromBundle de la clase atlas.componentes.utiles.AtlasFacesUtils.
Estructura y decoración de la página
En muchos casos surge la necesidad de implementar un mecanismo mediante el cual mantengamos una
estructura (“layout”) consistente entre todas las páginas que conforman la aplicación Web, lo que implicará
tener elementos comunes de página para ser implementados como componentes reutilizables.
La tecnología elegida para lograr esto es Facelets, que permite incluir plantillas reutilizables de forma
dinámica implementando de forma abstracta el patrón composite view y decorator.
Facelets es un lenguaje basado en plantillas que utiliza el concepto de “árbol de componentes” fomentando
la reutilización, permitiendo definir componentes como composición de otros componentes.
Podemos destacar las siguientes características sobre Facelets:
·
Trabajo basado en plantillas.
·
Basado en la composición de componentes.
·
Creación de etiquetas lógicas a la medida.
·
Soporte completo a EL, incluyendo funciones.
·
Desarrollo amigable para el diseñador gráfico gracias al concepto de “decorador”.
·
Creación de librerías de componentes.
·
Lenguaje integrado son JSTL.
·
No son necesarios ficheros de configuración XML.
·
El API de facelets son totalmente independientes del contenedor.
41 de 198
Framework Atlas
Normativa
Dentro del framework Atlas se han creado los distintos layouts que tienen que utilizar las aplicaciones
desarrolladas con este framework. El uso de estos layouts garantiza la homogeneidad de los desarrollos y
facilita el mantenimiento de los mismos.
Los layouts que ofrece el framework son:
hc.xhtml
(Horizontal+Contenido).
Incluye un menú horizontal, y en
el resto de la página se muestra
el contenido.
hvc.xhtml: (Horizontal+Vertical+Contenido).
Incluye un menú horizontal, uno
vertical y en el resto de la página
se muestra el contenido.
42 de 198
Framework Atlas
Normativa
hv.xhtml
(Horizontal+Visual).
Incluye un menú horizontal, y en
el resto de la página se muestra
el menú visual.
hvv.xhtml (Horizontal+Vertical+Visual).
Incluye un menú horizontal,
menú vertical y en el resto de la
página se muestra el menú
visual.
vc.xhtml
(Vertical + Contenido).
Incluye un menú vertical, y en el
resto de la página se muestra el
contenido.
43 de 198
Framework Atlas
Normativa
vv.xhtml:
(Vertical + Visual).
Incluye un menú vertical, y en el
resto de la página se muestra el
menú visual.
c.xhtml
(Contenido)
Incluye solamente la cabecera y
NORMA
el pie.
JSFLayout
El layout de páginas web debe ser alguno de los que ofrece el framework Atlas.
Ejemplo de uso de layout con menú vertical
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:atlas="http://atlas.core.componentes/jsf"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:a4j="http://richfaces.org/a4j"
44 de 198
Framework Atlas
Normativa
xmlns:rich="http://richfaces.org/rich"
version="2.0">
<jsp:text>
<![CDATA[ <?xml version="1.0" encoding="UTF8" ?> ]]>
</jsp:text>
<jsp:text>
<![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
]]>
</jsp:text>
<html xmlns="http://www.w3.org/1999/xhtml">
<ui:composition template="/WEB-INF/layout/vc.xhtml">
<ui:define name="rastroMigas">
<ui:include src="/secure/rastroMigas/rastro.xhtml" />
</ui:define>
<ui:define name="menuVertical">
<ui:include src="/secure/menu/menu.xhtml" />
</ui:define>
<ui:define name="content">
. . . Aqui se pondría el contenido de nuestra página
</ui:define>
</ui:composition>
</html>
</jsp:root>
NORMA
JSFPanel
La ubicación de los distintos elementos que forman la página se realizará con los componentes
que JSF ofrece: PanelGrids y PanelGroup.
No se utilizarán directamente tablas de html.
Los componentes de menús de ATLAS permiten técnicamente la definición de menús personalizados por
usuario. Sin embargo, el uso de menús personalizados por usuario puede aumentar el consumo de
memoria de la aplicación, ya que dichos menús se almacena en la Sesión del usuario.
Por este motivo, se prohíbe el uso de menús personalizados por usuario, en el caso de que se deseen
utilizar menús personalizados se debe solicitar la correspondiente autorización a ICM justificando dicha
necesidad.
45 de 198
Framework Atlas
Normativa
NORMA
JSFCustomMenu
Se prohíbe el uso de menús personalizados por usuario.
En el caso de que se deseen utilizar menús personalizados se debe solicitar la correspondiente
autorización a ICM justificando dicha necesidad.
6.2.1.7
Uso de javascript
JSFJavascript
Se debe minimizar el uso de Javascript y el código javascript que se incluya debe ser compatible
NORMA
con los navegadores.
En el caso de utilizar codigo javascript este se implementará mediante funciones que se ubicarán
en ficheros xxxx.js. Donde xxxx es el nombre de la aplicación.
Los ficheros de javascript deberán ubicarse dentro de la carpeta src/main/webapp/js.
Los ficheros js que se incluyen en los arquetipos no pueden ser modificados.
jQuery es una biblioteca de JavaScript que permite simplificar la manera de interactuar con los
documentos HTML, manipular el árbol DOM, manejar eventos, desarrollar animaciones y agregar
interacción con la técnica AJAX a páginas web. Por lo tanto si se requiere realizar algunas de estas
operaciones en las aplicaciones Atlas se deberá utilizar este framework.
Este framework javascript ya viene incluido en la distribución de RichFaces que viene configurada en los
arquetipos de ATLAS, por lo que no será necesario incluir ningún fichero adicional en el proyecto.
NORMA
JSFJQuery
Solo está permitido el uso del framework javascript JQuery que viene incluido en la versión de
RichFaces. No se podrán incluir frameworks diferentes a este ni otras versiones que no sea la
interna de RichFaces.
Para usar JQuery en el proyecto, se han de tener en cuenta las siguientes consideraciones:
6.2.1.7.1
Uso de JQuery en páginas JSF
Para usar JQuery en nuestras páginas JSF será necesario incluir esta sentencia en la página “.xhtml”:
Sentencia a incluir en la página “.xhtml” para utilizar jQuery
<h:outputScript name="jquery.js" target="head" />
De esta forma se estará haciendo uso de la versión interna de Richfaces.
46 de 198
Framework Atlas
Normativa
6.2.1.7.2
Uso del objeto JQuery
Para usar el objeto JQuery, no se podrá utilizar el alias ‘$’, que es de uso común en este framework, ya
que da problemas con las expresiones JSF. A continuación se muestran dos ejemplos uno que NO
Funciona y otro que SI funciona:
Uso del objeto JQuery en página xhtml
<h:outputScript name="jquery.js" target="head" />
<h:outputScript>
$('#elementId').text('Nuevo contenido');
// NO funciona
jQuery('#elementId').text('Nuevo contenido'); // SI funciona
</h:outputScript>
6.2.1.7.3
Uso de ready en sustitución del evento onLoad
En ocasiones es necesario realizar acciones una vez se haya cargado la página. Normalmente se hace
uso del evento onLoad del tag body que es invocado una vez que se ha cargado toda la página. Se
recomienda, en lugar de utilizar ese evento, hacer uso del método ready del objeto JQuery ya que este
método se ejecuta una vez inicializado el árbol DOM de la página en el navegador.
A continuación se muestra un ejemplo:
Sustitución de onLoad por evento ready
<h:outputScript name="jquery.js" target="head" />
<h:outputScript>
jQuery(document).ready(function() {
// Incicializar pagina
...
});
</h:outputScript>
6.2.1.7.4
Localización de elementos por Id
Cuando se quiere localizar un elemento de la página por su identificador, el carácter de composición usado
por JSF ‘:’ genera problemas con JQuery, ya que también es un operador de selección. Por lo tanto para
no tener problemas hay que transformarlo para escaparlo antes de pasarlo a JQuery.
A continuación se muestra un ejemplo:
Escapado para poder localizar elementos por Id
<h:outputScript name="jquery.js" target="head" />
<h:form id="formularioDatos">
<f:subview id="vista1">
<h:inputText id="nombre" /> <!-- id='formularioDatos:vista1:nombre' -->
</f:subview>
47 de 198
Framework Atlas
Normativa
</h:form>
<h:outputScript>
nombreId = '#{rich:clientId(“nombre”)}'.replace(/:/g, '\\:');
jQuery(‘#’ + nombreId).value = ‘ATLAS’;
</h:outputScript>
La operación marcada en amarillo en el ejemplo anterior obtiene el Id real del elemento ‘nombre’
(formularioDatos:vista1:nombre), mientras que la parte marcada en verde lo modifica para su uso con
jQuery (formularioDatos\:vista1\:nombre).
6.2.1.8
Normas de estilo
Existe un documento llamado “Atlas Guía de Estilo” que incluye información sobre:
o
Estilo de las aplicaciones
o
Accesibilidad
o
Usabilidad
Es necesario leer este documento antes de abordar la implementación de las páginas JSF.
NORMA
JSFAccesibilidad
Las aplicaciones de la Comunidad de Madrid que se publiquen en Internet tendrán que cumplir un
Nivel de Conformidad "A" de WCAG, esto implicará que las aplicaciones sean estrictas en el
cumplimiento de las normas de prioridad 1 especificadas en el Anexo Guía de Estilo del
NORMA
framework Atlas.
JSFImagenes
Las imágenes a utilizar en las aplicaciones del framework Atlas deberán ubicarse dentro de la
carpeta src/main/webapp/img
48 de 198
Framework Atlas
Normativa
JSFCSS
Las hojas de estilo se ubicaran en la carpeta src/main/webapp/css. Dentro de esta carpeta se
encuenta un fichero llamado atlas.css que incluye los estilos de Atlas. Este fichero no se puede
NORMA
modificar.
En el caso de necesitar nuevos estilos estos se crearán dentro de un fichero con la siguiente
nomenclatura
xxxx.css
Donde xxxx es el nombre de la aplicación.
Nunca se podrán definir estilos directamente dentro de una página.
NORMA
JSFIFRAMES
Se prohibe la utilización de IFrames. En el caso de que sea necesario utilizarlos es necesario
consultar previamente a su utilización a la Unidad de Arquitectura y Software de Aplicaciones
justificando debidamente su necesidad.
6.2.1.9
Interfaces ricas de usuario (RIA)
Existen tecnologías que pretenden mejorar las aplicaciones web asemejándolas todo lo posible a las
aplicaciones de escritorio tradicionales.
La arquitectura de ICM permite crear aplicaciones RIA utilizando AJAX de dos maneras:
·
Mediante la librería Ajax4JSF
·
Usando los componentes JSF del framework Atlas que poseen comportamiento asíncrono con
AJAX de forma transparente.
Ajax4JSF se incluye dentro de los componentes RichFaces. Es una librería open source que se integra
totalmente en la arquitectura de JSF y extiende la funcionalidad de sus etiquetas dotándolas con tecnología
Ajax de forma limpia y sin añadir código Javascript.
Mediante esta librería se puede variar el ciclo de vida de una petición JSF, recargar determinados
componentes de la página sin necesidad de recargarla por completo, realizar peticiones al servidor
automáticas, control de cualquier evento de usuario, etc.
Esta aproximación tiene las siguientes ventajas:
49 de 198
Framework Atlas
Normativa
·
La cantidad de javascript que hay que escribir (y mantener) es mínima. Esto reduce enormemente
el tiempo de depuración y pruebas necesarias cuando se trabaja en un entorno multi-navegador.
·
Fácil integración: Ajax4JSF apenas requiere la modificación del código existente.
·
Soporte Facelets: Es una solución que se integra a la perfección con la tecnología de decoración y
estructura de páginas, es decir, facelets.
·
Compatibilidad. No es necesario desarrollar otra aplicación para cuando el navegador no soporta
AJAX. En este caso, la aplicación se comportará de la forma tradicional, refrescando la página
completa.
NORMA
JSFAjax
Si se desea dotar de capacidades AJAX a las páginas JSF se utilizará Ajax4JSF. El uso de
cualquier otra tecnología RIA deberá ser consensuado previamente con ICM.
El arquetipo web ya viene configurado para trabajar con Ajax4JSF.
La forma mas sencilla de incluir ajax4JSF en una página es incluir una región y todo lo que se incluya
dentro de esta se refrescará parcialmente.
Ejemplo de uso de región ajax
<a4j:form id="allRoomsForm2" ajaxSubmit="true"
reRender="roomsTable,scroll_1,scroll_2" status="ajaxStatus">
<a4j:region id="region1" selfRendered="true">
…..
</a4j:region>
</a4j:form>
NORMA
JSFAjaxInterac
La invocación de funcionalidad AJAX debe ser siempre consecuencia de una interacción con el
usuario, por ejemplo, al seleccionar el valor de un combo, se carga de manera dinámica los
valores de otro.
En concreto, la carga inicial de una página no debe implicar la ejecución de funcionalidad AJAX.
50 de 198
Framework Atlas
Normativa
JSFAjaxLimite
Se recomienda limitar la cantidad de información intercambiada mediante AJAX.
PRACTICA
BUENA
Para esto se recomienda restringir las regiones AJAX de modo que se procese el mínimo
número de componentes. Las regiones se pueden anidar y no es necesario que los
componentes que se vayan a actualizar estén dentro de la región.
También se recomienda el uso del atributo AjaxSingle en aquellas situaciones en las que sólo
sea necesario que se procese el componente que desencadena el evento.
Por último, en ocasiones es preferible recargar la página de nuevo, a intercambiar mediante
AJAX gran cantidad de información, y utilizar componentes estándar a utilizar componentes
AJAX si no se va a hacer uso de propiedades específicas del componente.
51 de 198
Framework Atlas
Normativa
6.2.1.10 Ayuda contextual
La ayuda contextual en una aplicación favorece y mejora la experiencia de usuario facilitando el uso de la
aplicación. Para incluir este tipo de ayuda en una página de nuestra aplicación utilizaremos el icono
que
podemos encontrar en la ruta “src/main/webapp/img ico_ayuda.gif” de los arquetipos.
Dentro de los formularios JSF se puede incluir ayuda contextual para cada uno de los elementos
mediante el uso de la etiqueta de richfaces rich:toolTip. Mediante esta etiqueta se muestra un pequeño
popup no modal en el cual se puede mostrar información adicional.
Ejemplo de uso de rich:toolTip en un campo de un formulario
<h:panelGrid columns="2" cellpadding="0" cellspacing="0">
<h:inputText id="inputTextClienteNombre" size="50" maxlength="50"
styleClass="cajaTexto" required="false"
value="#{clienteBean.nombreFilter}"
onkeypress="trapEnter(event,'filterPanel:filtrarLink',true);"/>
<a4j:outputPanel styleClass="paddingleft5">
<h:graphicImage value="img/ico_ayuda.gif"
alt="#{bundle['tooltipFilter.clientenombre']}"/>
<rich:tooltip value="#{bundle['tooltipFilter.clientenombre']}"/>
</a4j:outputPanel>
</h:panelGrid>
El mensaje a mostrar dentro del tooltip se ha de obtener del fichero de mensajes de la aplicación tal y
como se puede ver en el ejemplo anterior.
En los arquetipos de Atlas se han incluido ejemplos de uso de tooltip en los formularios de ejemplo, y la
herramienta de generación automática de código también genera estos tooltips en las páginas de listados y
detalles de entidades.
Si se desea una ayuda contextual más completa a nivel de página se hará utilizando el componente
<atlas:panelAyuda> que muestra un icono
en la parte superior derecha que enlaza con la página xhtml
de ayuda correspondiente a dicha página. Esta página se muestra en un popup no modal para que pueda
ser visualizada mientras se está trabajando con la aplicación. Las páginas de ayuda se incluirán en una
carpeta llamada help y la nomenclatura de las mismas deberá ser la misma de la página original más un
sufijo _help.
Para más información consultar el manual de usuario ATLAS_MUS_Componente_Panel_ayuda.
52 de 198
Framework Atlas
Normativa
En la siguiente página podemos ver el icono que enlaza con la ayuda en la parte superior derecha de la
página.
Al pulsar sobre el icono nos mostrará el panel de la ayuda de la siguiente forma:
PRACTICA
BUENA
JSFAYUDA
6.2.2
Se recomienda incluir ayuda contextual en las aplicaciones utilizando el componente
rich:toolTip para elementos individuales y atlas:panelAyuda para ayudas a nivel de página.
MANAGED BEANS
53 de 198
Framework Atlas
Normativa
Los managed beans o beans de respaldo son las clases que incluyen los atributos y métodos que van a
ser invocados desde las páginas JSF.
Los distintos métodos que puede tener un managed bean son:
1. Gettter y setter de los atributos
2. Métodos manejadores de eventos de acción
3. Métodos de manejo de eventos de cambio de valor
4. Métodos de acción
JSFMBeansImpl
Dentro de una aplicación en cada bloque funcional se han de crear los managed beans que darán
NORMA
cobertura a las peticiones de las páginas JSF.
La nomenclatura de estas clases será:
<nombre>Bean
Donde <nombre> debe ser sustituido por el nombre del Bean.
Estas clases Java se crearán en el paquete jsf dentro del bloque funcional correspondiente.
A continuación se muestra parte de un ejemplo de managed bean. El ejemplo completo se puede ver
dentro del arquetipo de aplicaciones web.
ClientesBean.java
package ejpl.gestion.jsf;
import …
/**
* Esta clase representa el Backing Bean
* para las páginas que hagan uso de la
* entidad ejpl.gestion.domain.Cliente .
* @author ICM
* @version 1.0.
*/
@Component
public class ClientesBean {
/**
* Identificador del numero de serie para serializacion
*/
private static final long serialVersionUID = 1L;
/**
* Servicio de la fachada
*/
54 de 198
Framework Atlas
Normativa
private GestionFacade facade;
/**
* Cliente actual
*/
private Cliente cliente = null;
/**
* Filtro para el nombre del cliente
*/
private String nombreCliente = null;
/**
* Constructor por defecto.
* <p>
* Se realizan las operaciones de
* inicialización para los Managed Beans
*/
public ClientesBean() {
this.cliente = new Cliente();
cliente.setEstadoCivil(new EstadoCivil());
}
/**
* @return <code>ejpl.gestion.domain.Cliente</code> Devuelve el objeto de
* dominio cliente asociado al Backing Bean.
*/
public Cliente getCliente() {
return this.cliente;
}
/**
* @param cliente <code>ejpl.gestion.domain.Cliente</code> Modifica el
* objeto de dominio asociado al Backing Bean.
*/
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
/**
* Este metodo obtiene un cliente a partir de un identificador/PK obtenida
* de la request.
*
* @throws atlas.core.exceptions.ServiceException
* Lanza atlas.core.exceptions.ServiceException ante cualquier error
* @return <code>java.lang.String</code> Devuelve la regla de navegacion
* <code>NavigationResults.MODIFICAR_CLIENTE</code>.
*/
public String cargarCliente() throws ServiceException {
String paramIdCliente =
AtlasFacesUtils.getFromRequest(FacesContext.getCurrentInstance(),
"idCliente");
try {
if (paramIdCliente != null) {
Integer idCliente = Integer.valueOf(paramIdCliente);
this.cliente = facade.obtenerClientePorId(idCliente);
}
} catch (ServiceException se) {
55 de 198
Framework Atlas
Normativa
AtlasFacesUtils.storeOnRequestError(FacesContext.getCurrentInstance(),
"error.CLIENTES_OBTENER", se);
// return NavigationResults.MOSTRAR_ERROR;
throw se;
}
return NavigationResults.MODIFICAR_CLIENTE;
}
/**
* Este metodo inserta o modifica un cliente en el sistema.
*
* @throws atlas.core.exceptions.ServiceException Lanza
*
atlas.core.exceptions.ServiceException ante cualquier error
*
producido.
* @return <code>java.lang.String</code> Devuelve la regla de navegacion
*
<code>NavigationResults.VOLVER_LISTADO_CLIENTES</code>.
*/
public String guardarCliente() throws ServiceException {
try {
facade.insertOrUpdateCliente(cliente);
} catch (ServiceException se) {
AtlasFacesUtils.storeOnRequestError(FacesContext.getCurrentInstance(),
"error.CLIENTES_MODIFICAR", se);
// return NavigationResults.MOSTRAR_ERROR;
throw se;
}
return NavigationResults.VOLVER_LISTADO_CLIENTES;
}
...
}
NORMA
JSFAnotacion
Las clases que representan los Managed Beans de JSF deberán tener la anotación
“@Component”.
NORMA
JSFMBAtributos
Los atributos de un managed bean se definirán como privados, con métodos get y set para
aquellas propiedades que vayan a ser vinculadas a un componente de una página JSF.
PRACTICA
BUENA
JSFMBunico
Se recomienda crear un managed bean por cada página JSF, de tal manera que tanto los datos
como el comportamiento de esta página sean manejados por el bean en cuestión. Un managed
bean no debería mezclar atributos o comportamientos de dos páginas que no estén
relacionadas.
56 de 198
Framework Atlas
Normativa
El acceso a los datos persistentes deberá realizarse a través de la capa de negocio, haciendo uso de la
fachada que dicha capa expondrá a tal efecto. Además no está permitida la invocación directa a servicios
de negocio sin pasar por la fachada.
class j sf
ClientesBean
Página JSF
-
cliente: Cliente = null
clientesScroller: HtmlDataScroller = new HtmlDataScr...
facade: GestionFacade
nombreCliente: String = null
orderAndFilterClientes: OrderAndFilterBean = null
serialVersionUID: long = 1L {readOnly}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
cargarCliente() : String
ClientesBean()
filtrar() : String
getCliente() : Cliente
getClientesScroller() : HtmlDataScroller
getFacade() : GestionFacade
getNombreCliente() : String
getOrderAndFilterClientes() : OrderAndFilterBean
getTimeZone() : T imeZone
guardarCliente() : String
nuevoCliente() : String
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
setCliente(Cliente) : void
setClientesScroller(HtmlDataScroller) : void
setEstadoCivil(String) : void
setFacade(GestionFacade) : void
setIdEstadoCivil(String) : void
setNombreCliente(String) : void
setOrderAndFilterClientes(OrderAndFilterBean) : void
volver() : String
«interface»
facade::GestionFacade
+
-facade +
+
+
+
+
+
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
updateCliente(Cliente) : void
NORMA
JSFFacade
6.2.2.1
El acceso a la capa de negocio desde los managed beans siempre se debe hacer a través de la
fachada. Esto implica que desde las clases managed beans no se puede invocar ni DAOs ni
ningún servicio que no sea la fachada.
Manejo de excepciones
JSF no ofrece un mecanismo automático para el manejo de las excepciones producidas dentro de los
managed beans, aunque si dispone de ciertos elementos que ayudan en la gestión de las mismas.
Dentro del API de JSF existe una clase que permite mostrar mensajes genéricos (normalmente mensajes
de error) llamada FacesMessage. Añadiendo un objeto de esta clase al contexto de la JSF, este mensaje
se puede mostrar en cualquier JSF mediante una etiqueta estándar. Mediante el uso de esta clase,
podemos tratar las excepciones de los beans de la aplicación, de forma que cuando se produzcan se
almacene uno de estos mensajes:
57 de 198
Framework Atlas
Normativa
JSFException
Todos los métodos de los managed beans que hagan uso de la fachada, tratarán las excepciones
que esta pueda lanzar, que siempre serán de tipo “ServiceException” o clases que hereden de
esta.
La forma de manejar la excepción dependerá del origen de la misma, distinguiendo entre
NORMA
excepciones de negocio (excepción creada a medida) y excepciones del sistema.
o
En el primer caso, se atrapará la excepción y se implementará el código que deseemos
que se ejecute en base a las reglas de nuestro negocio. Es decir, si por ejemplo se
produce una supuesta excepción (creada a medida) “BlockedUserException” indicando
que un usuario está bloqueado, se podría implementar una funcionalidad que redirija la
petición inicial a otra aplicación externa que permita desbloquear la cuenta del usuario.
o
En el segundo caso, siempre se redirigirá a una página de error que extraerá la excepción
encapsulada dentro del “ServiceException” (como por ejemplo una
“DataAccessException”) mostrando un mensaje “amigable” al usuario final en función de
la excepción manejada.
Los métodos del bean podrían manejar las excepciones de la siguiente forma:
Ejemplo de manejo de excepciones
/**
* Este metodo inserta o modifica un cliente en el sistema.
*
* @throws atlas.core.exceptions.ServiceException Lanza
*
atlas.core.exceptions.ServiceException ante cualquier error
*
producido.
* @return <code>java.lang.String</code> Devuelve la regla de navegacion
*
<code>NavigationResults.VOLVER_LISTADO_CLIENTES</code>.
*/
public String guardarCliente() throws ServiceException {
try {
facade.insertOrUpdateCliente(cliente);
} catch (ServiceException se) {
}
AtlasFacesUtils.storeOnRequestError(FacesContext.getCurrentInstance(),
"error.CLIENTES_MODIFICAR", se);
throw se;
}
return NavigationResults.VOLVER_LISTADO_CLIENTES;
}
Cuando se produce una excepción, el método está almacenando un mensaje en el contexto de JSF. Para
presentar el error tendríamos que incluir en la página JSF la etiqueta h:message.
58 de 198
Framework Atlas
Normativa
PRACTICA
BUENA
JSFStoreError
Para enviar el mensaje de error de una excepción a la página jsf se recomienda utilizar el
método storeOnRequestError de la clase atlas.componentes.utiles.AtlasFacesUtils. Este
metodo deja en el contexto de JSF el mensaje de error para que luego pueda se capturado por
la etiqueta h:message.
También se manejarán las excepciones que puedan producirse en otros puntos del bean (constructor,
método init, listeners, etc.).
6.2.2.2
Navegación
JSFNavegacion
Los valores posibles para la navegación dinámica de los managed beans se han de almacenar en
NORMA
una clase aparte, para tenerlos todos localizados en un mismo lugar.
Esta clase debe llamarse NavigationsResults y ubicarse en el paquete jsf de cada bloque
funcional. En el caso de que se tengan varios bloques funcionales hay que añadir por delante el
nombre del bloque funcional para poder distinguir una clase de otra. (Ejemplo
<bloquefuncional>NavigationResults).
En esta clase se definirán como constantes (public static final String) todos los
caminos de la navegación.
A continuación se muestra un ejemplo de esta clase
NavigationResults.java
package ejpl.gestion.jsf;
/**
* Esta clase representa constantes asociadas
* a las reglas de navegacion de la aplicacion.
* @author ICM
* @version 1.0.
* @since Atlas 1.0.0.
*/
public final class NavigationResults {
/**
* Constructor para que no se genere el publico por defecto
59 de 198
Framework Atlas
Normativa
*/
protected NavigationResults() {
}
/**
* Operacion de navegacion: Resultado de la operacion correcto.
*/
public static final String SUCCESS = "success";
/**
* Operacion de navegacion: Resultado de la operacion fallido.
*/
public static final String FAILURE = "failure";
/**
* Operacion de navegacion: Salir de la aplicacion.
*/
public static final String LOGOUT = "logout";
/**
* Operacion de navegacion: Nuevo Cliente.
*/
public static final String NUEVO_CLIENTE = "nuevoCliente";
/**
* Operacion de navegacion: Modificar Cliente.
*/
public static final String MODIFICAR_CLIENTE = "modificarCliente";
/**
* Operacion de navegacion: Eliminar Cliente.
*/
public static final String ELIMINAR_CLIENTE = "eliminarCliente";
/**
* Operacion de navegacion: Volver al listado de Clientes.
*/
public static final String VOLVER_LISTADO_CLIENTES =
"volverListadoClientes";
/**
* Operacion de navegacion: Mostrar pagina de error.
*/
public static final String MOSTRAR_ERROR = "mostrarError";
}
Los métodos de las clases managed beans deberán utilizar estas variables en la respuesta de los métodos
de acción tal y como se puede ver en los ejemplos anteriormente expuestos.
Los elementos de navegación indicados en el fichero NavigationResults deberán ser utilizados en el fichero
de JSF de configuración de la navegación tal y como se comenta en el apartado 2.1.3.3 facesnavigation.xml.
60 de 198
Framework Atlas
Normativa
6.2.2.3
Inicialización de los Beans (@PostContruct)
Algunas veces se necesita realizar alguna acción nada más crearse un bean. Por ejemplo el caso que
necesitemos recoger en un Bean los parámetros que se pasan por la URL, o por cualquier otra causa.
Si se anota un método de un bean con @PostContruct este método se llamará nada más crear el bean.
Ejemplo de un método que recoge el parámetro token de la url.
Ejemplo de miBean.java
@PostConstruct
public void inicializarBean() {
String token = AtlasFacesUtils.getRequestParameter("token");
setAppToken(token);
…
}
6.2.3
Configuración de JSF
Para realizar la configuración necesaria para los componentes JSF de las aplicaciones del framework Atlas
tenemos que tener en cuenta que esta configuración se encuentra dentro de tres ficheros. Estos ficheros
los podemos encontrar en el arquetipo web previamente configurados en el directorio
src/main/webapp/WEB-INF.
Fichero de configuración
Descripción
faces-config.xml
Fichero principal de configuración de JSF. No se puede modificar este
fichero.
faces-managed-beans.xml
Fichero donde se definen los managed beans de la aplicación en caso de
no usar anotaciones.
faces-navigation.xml
Fichero donde se configuran las reglas de navegación de la aplicación.
6.2.3.1
faces-config.xml
El fichero de configuración faces-config.xml ya incluye:
o
Configuración de los resolver de variables y propiedades que permiter inyectar beans de Spring en
los managed beans.
o
Configuración de los ficheros de mensajes y de los locales.
61 de 198
Framework Atlas
Normativa
NORMA
JSFfacesconfigxml
La configuración que se encuentra dentro del fichero faces-config.xml del arquetipo no se puede
modificar. En el caso de que se desee modificar se debe solicitar la correspondiente autorización
a ICM justificando dicha necesidad.
6.2.3.2
faces-managed-beans.xml
La definición de los managed beans puede hacerse de dos maneras: mediante un fichero de configuración
o con anotaciones, para el primer caso utilizaremos el fichero faces-managed-beans.xml.
La forma de añadir managed beans es la siguiente:
Ejemplo de configuración de managed bean
<managed-bean>
<description>Bean de clientes</description>
<managed-bean-name>clientesBean</managed-bean-name>
<managed-bean-class>
ejpl.gestion.jsf.ClientesBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>facade</property-name>
<value>#{facade}</value>
</managed-property>
<managed-property>
<property-name>orderAndFilterClientes</property-name>
<value>#{orderAndFilterClientes}</value>
</managed-property>
</managed-bean>
Uso del contexto dentro del faces-managed-beans.xml
El contexto de una aplicación Web permite el almacenamiento de información relevante a lo largo de la
ejecución de diversas operaciones por parte del usuario.
Las decisiones sobre el mantenimiento del estado tienen impacto en el rendimiento de la aplicación, así
como en la disponibilidad y la escalabilidad. Estas decisiones incluyen elegir la capa de la aplicación donde
manejar el estado, el ámbito apropiado para cada elemento a almacenar y como mantener el estado en un
entorno distribuido.
En las aplicaciones JEE el estado tiene distintos ámbitos, entendiéndose como ámbito a los distintos
lugares desde donde ese estado es accesible. Resumiendo, se puede decir que el estado en la capa de
presentación se puede mantener en cuatro ámbitos.
62 de 198
Framework Atlas
Normativa
JSF amplia estos ámbitos, permitiendo guardar y restaurar el estado de los componentes para cada
petición tanto en el cliente como en el servidor:
Ámbito
Descripción
Aplicable sólo a páginas JSF contiene datos que solo son válidos en el contexto de una
Página
página.
Cuando una JSF redirige o incluye a otra, cada página define su propio estado.
Petición
Permite almacenar información que será accesible por todos los componentes Web que
intervengan en esa petición hasta que se genere la respuesta al usuario.
Sesión
Permite almacenar información que será accesible por todos los componentes Web durante la
sesión del usuario, que durará desde que el usuario entre en la aplicación hasta que salga de
ella o transcurra un tiempo máximo de inactividad.
Aplicación Permite almacenar información que será accesible por todos los componentes de la aplicación
web en cualquier momento (mientras la aplicación esté activa).
Cliente
El árbol de componentes JSF se guarda en un campo oculto dentro de la petición Http
Servidor
El árbol se almacena en la sesión Http
NORMA
Para definir el contexto de un managed bean se utiliza el atributo managed-bean-scope.
JSFRequest
Los managed beans deben ser siempre de ámbito request, pudiendo ser de ámbito sesión tan
sólo en casos excepcionales y justificados.
Atlas amplia este modelo haciendo posible escribir aplicaciones sin necesidad del uso del HttpSession.
Toda la información tanto de la vista como del modelo (managed beans) puede ser codificada y enviada al
cliente. Esto se lleva a cabo mediante una etiqueta presente en la librería de componentes de Atlas:
<atlas:guardarEstado>
<atlas:guardarEstado id="save1" value="#{calcForm.number1}" />
El único requisito para poder almacenar un objeto completo, es que el bean implemente el interfaz
java.io.Serializable
63 de 198
Framework Atlas
Normativa
JSFSavestate
El problema principal del almacenamiento de información (tanto del árbol de componentes
PRACTICA
BUENA
como de los managed beans) es el rendimiento.
El tiempo de serialización y deserialización de los objetos aumenta considerablemente el
tiempo de respuesta ante una petición, del mismo modo que el ancho de banda consumido (y
por tanto de tiempo de transferencia de las páginas).
Por lo tanto se recomienda reducir el uso del componente guardarEstado a casos
imprescindibles.
6.2.3.3
faces-navigation.xml
El fichero de configuración faces-navigation.xml incluye las reglas de navegación de JSF.
Presenta dos tipos de navegación:
· Estática: cuando desde una página se va directamente a otra. Esto se hace definiendo las reglas
de navegación en el fichero de configuración.
· Dinámica: cuando una acción o cierta lógica determina la página a la que navegar. Esto lo soporta
permitiendo que los componentes definan como destino de su navegación el resultado de una
consulta a un manejador de acciones, donde se codifica la navegación dinámica, frente a la
definición de un destino fijo.
A continuación se muestra un ejemplo de las reglas de navegación para una aplicación simple:
64 de 198
Framework Atlas
Normativa
Ejemplo de faces-navigation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config
PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<!-- ============================================================== -->
<!-Fichero donde se definen todas
-->
<!-las reglas de navegación de la aplicación
-->
<!-- ============================================================== -->
<faces-config>
<navigation-rule>
<description>
Reglas de navegacion para la pagina index.xhtml
</description>
<from-view-id>/secure/index.xhtml</from-view-id>
<navigation-case>
<from-outcome>nuevoCliente</from-outcome>
<to-view-id>/secure/formularioCliente.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>modificarCliente</from-outcome>
<to-view-id>/secure/formularioCliente.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>eliminarCliente</from-outcome>
<to-view-id>/secure/index.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<description>
Reglas de navegacion para la pagina formularioCliente.xhtml
</description>
<from-view-id>/secure/formularioCliente.xhtml</from-view-id>
<navigation-case>
<from-outcome>volverListadoClientes</from-outcome>
<to-view-id>/secure/index.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
…
NORMA
</faces-config>
JSFNavDes
Se ha de ofrecer un comentario explicativo en el atributo description para cada regla de
navegación definida en el archivo de configuración navigation-rule.xml
Mediante reglas de navegación de JSF se puede hacer uso de patrones, de forma que una serie de
páginas lleven a una dada:
65 de 198
Framework Atlas
Normativa
Ejemplo de regla de navegación con patrones
<navigation-rule>
<description>
Regla de navegación para todas las páginas de la carpeta pages
</description>
<from-view-id>/pages/*</from-view-id>
<navigation-case>
<from-outcome>menu</from-outcome>
<to-view-id>/menu/main_main.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>info</from-outcome>
<to-view-id>/menu/info.jsp</to-view-id>
</navigation-case>
</navigation-rule>
También se pueden especificar destinos “globales” de forma que desde cualquier página se pueda navegar
una dada.
El siguiente ejemplo muestra como con esta característica se puede implementar una opción de ayuda
global para la aplicación:
Ejemplo de regla de navegación global
<navigation-rule>
<navigation-case>
<from-outcome>globalhelp</from-outcome>
<to-view-id>/menu/generalHelp.jsp</to-view-id>
</navigation-case>
</navigation-rule>
66 de 198
Framework Atlas
Normativa
6.2.3.4
Archivos de configuración adicionales y web.xml
JSFConfAdicional
Si el tamaño de los ficheros faces-managed-beans.xml o faces-navigation.xml creciese en
exceso, se permite crear ficheros adicionales que agrupen los beans/reglas por funcionalidad.
NORMA
Dichos ficheros deberán denominarse:
-
faces-managed-beans-yyyy.xml
-
faces-navigation-yyyy.xml
Donde yyyy puede ser cualquier término en minúsculas que sea representativo de la funcionalidad
que agrupan los ficheros.
Además, en el parámetro javax.config.CONFIG_FILES del archivo web.xml del proyecto deberá
añadirse referencias a los nuevos ficheros de configuración.
El fichero de configuración web.xml del arquetipo ya viene preconfigurado con todos los parámetros de
configuración de JSF.
NORMA
JSFwebxml
La configuración de JSF que se encuentra en el arquetipo dentro del fichero de configuración
web.xml no se puede modificar (excepto el parámetro javax.config.CONFIG_FILES si se
incluyesen ficheros de configuración adicionales).
En el caso de que se desee modificar se debe solicitar la correspondiente autorización a ICM
justificando dicha necesidad.
6.2.3.5
Anotaciones
Como se ha comentado previamente existe la posibilidad de declarar un managed bean mediante
anotaciones. El efecto de declarar un bean con anotaciones o en el faces-managed-beans.xml es el
mismo.
Para declarar un bean usaremos la anotación @ManagedBean. La anotación tiene un atributo name, pero
si no se especifica el nombre por defecto del bean será el de la clase con la primera letra minúscula.
Para especificar el ámbito del bean se utilizará la anotación @RequestScoped (@SessionScoped,
@ApplicationScoped… para otros ámbitos).
67 de 198
Framework Atlas
Normativa
Para inicializar propiedades del bean se utiliza la anotación @ManagedProperty en la declaración de la
propiedad en el bean. La anotación tiene la propiedad value, que puede tener un valor literal o bien
referenciar otro objeto en el contexto.
Las anotaciones anteriores están en el paquete javax.faces.bean. A continuación se muestra un ejemplo
de anotaciones sobre la clase ClienteBean.
ClienteBean.java
package ejpl.gestion.jsf;
…
/**
* Bean de cliente
*/
@ManagedBean
@RequestScope
public class ClienteBean {
/**
* Servicio de la fachada
*/
@ManagedProperty(value=”#{facade}”)
private GestionFacade facade;
/**
* Bean para orden y filtro del listado
*/
@ManagedProperty(value=”#{orderAndFilterCliente}”)
private OrderAndFilterBean orderAndFilter;
…
}
68 de 198
Framework Atlas
Normativa
6.2.4
Uso de la Sesión
En el servidor de aplicaciones se crea un objeto sesión por cada usuario que se conecta, y se mantiene allí
durante un tiempo. Cuando una aplicación tiene mucha concurrencia, esto puede ser un problema grave en
un entorno de producción debido a la cantidad de memoria ocupada por estas sesiones. La situación se
complica en un entorno de clúster, en el que la información de sesión tiene que replicarse entre 2 o más
instancias del servidor de aplicaciones.
JSFSesion
NORMA
El contenido de la sesión nunca debe exceder los 4 Kbytes de tamaño
Cuando sea necesario almacenar una cantidad de información importante (superior a 4Kbytes)
durante un tiempo de vida superior a la petición, siempre y cuando haya sido previamente
autorizado por ICM, se implementará el mecanismo de persistencia en BBDD indicado por el
framework Atlas.
En cualquier caso se deben eliminar de la sesión los datos cuando ya no sean necesarios.
NORMA
JSFHttpSession
Se debe minimizar el uso del objeto HttpSession.
En caso de que se necesite solamente se podrá utilizar el objeto HttpSesion desde los managed
beans.
NORMA
NORMA
JSFTiempoSesion
El tiempo de vida de la sesión será establecido a nivel del servidor de aplicaciones, nunca se
definirá a nivel de la aplicación. Por tanto las aplicaciones no podrán depender de un valor
concreto de dicho tiempo para su correcto funcionamiento.
JSFUsoSesion
Cada vez que se acceda a un objeto de la sesión se debe comprobar previamente la existencia de
dicho objeto y actuar en consecuencia, para prevenir errores ante una pérdida de sesión.
69 de 198
Framework Atlas
Normativa
NORMA
JSFCreacionSesion
La sesión será creada automáticamente por el framework por lo tanto las aplicaciones no pueden
crearla, esto significa que no se puede obtener el objeto sesión de la siguiente forma:
request.getSession(true).
6.3
PRACTICA
BUENA
JSFAtlasFacesUtils
Para obtener o establecer elementos en la sesión utilizar los métodos creados para ellos en la
clase atlas.componentes.utiles.AtlasFacesUtils. También hay métodos similares para el
ámbito request.
SERVICIOS DE NEGOCIO
Los servicios de negocio son aquellos que implementan la lógica que complementa las operaciones de
acceso a datos para cubrir los requisitos de negocio de una aplicación.
La arquitectura de aplicaciones del framework Atlas busca simplificar la creación e integración de
aplicaciones de negocio, por lo que está construida en base a una arquitectura orientada a servicios (SOA).
En una arquitectura SOA, los servicios de negocio no tienen porqué ser implementados como servicios
web. El uso de servicios web debería limitarse a aquellos casos en los que realmente se vaya a sacar
provecho a esta aproximación.
Como norma general, se expondrán como servicios web aquellos servicios con una funcionalidad de
negocio que sea susceptible de ser reutilizada en otras aplicaciones, que ofrezcan una granularidad
1
gruesa e interfaces bien definidos. En este tipo de servicios, los interfaces han de definir el intercambio de
datos de negocio, no el intercambio de objetos. Para obtener mas información sobre los servicios web
dentro del framework Atlas ir al apartado 8. SERVICIOS WEB.
Para el resto de casos se emplearán servicios de negocio implementados como clases Java simples
(POJOs) con una clara orientación a servicio, haciendo uso de las funcionalidades que Spring ofrece.
1
Nivel de granularidad en la que el interfaz del servicio define relativamente pocos métodos de servicio
para conseguir un objetivo de negocio, mediante parámetros orientados a documento
70 de 198
Framework Atlas
Normativa
De esta forma en un momento dado uno de estos servicios puede ser expuesto como servicio web para ser
empleado por otras aplicaciones.
Los beneficios de esta aproximación son los siguientes:
·
Simplificación en el desarrollo de componentes de negocio.
·
Simplificación del ensamblaje y despliegue de soluciones de negocio construidas como redes de
servicios.
·
Aumento de la flexibilidad y agilidad.
·
Protección de la inversión en tecnología y lógica de negocio existente.
·
Simplificación de las pruebas.
Dentro de la capa de servicios vamos a identificar dos tipos de elementos:
o
Fachada
o
Servicios
La siguiente figura muestra un ejemplo de una parte de la capa de servicios del framework ATLAS:
class facade
«interface»
GestionFacade
+
+
+
+
+
+
+
serv ices::ClienteServ iceImpl
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
updateCliente(Cliente) : void
-
clienteDAO: ClienteDAO
+
+
+
+
+
+
+
+
+
ClienteServiceImpl()
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
setClienteDAO(ClienteDAO) : void
updateCliente(Cliente) : void
GestionFacadeImpl
-
clienteService: ClienteService
+
+
+
+
+
+
+
+
+
deleteCliente(Cliente) : void
GestionFacadeImpl()
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
setClienteService(ClienteService) : void
updateCliente(Cliente) : void
«interface»
services::ClienteService
+
-clienteService +
+
+
+
+
+
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List <Cliente>
obtenerTotalClientes(Object) : int
updateCliente(Cliente) : void
ATENCION
Aunque en este ejemplo se muestra solamente un servicio lo normal es que la fachada acceda a varios
servicios.
Los servicios se separarán en bloques funcionales para facilitar el mantenimiento posterior de la aplicación.
Cada bloque funcional estará formado por los objetos de dominio, los DAOs, los servicios y la fachada.
71 de 198
Framework Atlas
Normativa
6.3.1
FACHADA
En primer lugar nos encontramos con la fachada que será el punto central de acceso a los servicios de
negocio de un bloque funcional. Los componentes de la capa de presentación invocarán por tanto a esta
fachada.
La fachada constituye el lugar idóneo para poder gestionar de forma sencilla los aspectos transversales a
la arquitectura, tales como las transacciones, la seguridad, la auditoria de acceso a información protegida y
las trazas.
SNFacade
Dentro de una aplicación en cada bloque funcional se ha de crear un servicio que haga de
2
“fachada” al resto de servicios de negocio.
NORMA
Las responsabilidades de esta fachada son las siguientes:
o
Manejar las peticiones de la capa de presentación.
o
Recuperar los datos (en forma de objetos de dominio) que requiere la capa
de presentación.
o
Usar inyección de dependencias para crear los servicios de negocio.
o
Delegar la ejecución a los servicios de negocio.
Cada bloque funcional deberá tener una fachada y solo puede haber una fachada por cada
bloque funcional.
De esta manera, para acceder a la lógica de negocio de la aplicación se empleará siempre esta fachada.
Esto reduce el número de objetos a usar desde el cliente y el acoplamiento con la capa de servicios de
negocio, ya que un servicio puede ser reemplazado o modificado sin afectar a la capa de presentación de
la aplicación.
De forma general, la fachada delegará la ejecución de los métodos de negocio al correspondiente servicio
de negocio (que serán los que gestionen entre otras cosas la transaccionalidad). Aunque no es lo
recomendado, en ocasiones especiales se puede definir en la fachada algún método de más alto nivel que
implique el uso de varios servicios de negocio.
2
El patrón de diseño Facade (fachada) sirve para proveer de una interfaz unificada sencilla que haga de intermediaria
entre un cliente y una interfaz o grupo de interfaces más complejas.
72 de 198
Framework Atlas
Normativa
PRACTICA
BUENA
SNFacadeWS
En el caso de módulos de tipo servicio web la fachada no tiene sentido. Los que se publican
como servicios son los propios servicios de negocio. Si intervienen varios servicios de negocio
se puede crear un servicio de alto nivel que contenga la lógica de negocio e invoque al resto
de servicios.
SNFacadeImpl
NORMA
Para crear una fachada se crearán dos clases, con la siguiente nomenclatura:
o
<nombre>Facade (Interfaz de la fachada)
o
<nombre>FacaceImpl (Implementación de la interfaz)
Donde <nombre> debe ser sustituido por el nombre del bloque funcional al que pertenece la
fachada.
Estas clases se incluirán en el paquete services.facade del bloque funcional correspondiente.
class facade
«interface»
GestionFacade
+
+
+
+
+
+
+
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
updateCliente(Cliente) : void
GestionFacadeImpl
-
clienteService: ClienteService
+
+
+
+
+
+
+
+
+
deleteCliente(Cliente) : void
GestionFacadeImpl()
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
setClienteService(ClienteService) : void
updateCliente(Cliente) : void
Una de las implicaciones más importantes al trabajar con JSF es que de alguna manera lo que se presenta
al usuario dentro de un formulario es el propio objeto de dominio, generados por la capa de acceso de
datos y obtenidos a través de la fachada.
73 de 198
Framework Atlas
Normativa
NORMA
SNDominio
Los métodos de la fachada utilizarán objetos de dominio (esto es, los que representan los datos
de la aplicación) cuando sea necesario. No es necesario crear clases adicionales (los viejos
DTO, Data Transfer Objects) para enviar este tipo de datos.
A continuación se muestra un ejemplo de interfaz e implementación de una fachada.
Ejemplo de interfaz de una fachada
package ejpl.gestion.services.facade;
import java.util.List;
import ejpl.gestion.domain.Cliente;
import atlas.core.exceptions.ServiceException;
/**
* Esta interfaz representa las operaciones
* de la facacha del sistema.
* @author ICM
* @version 1.0
* @since ATLAS 1.0.0
*/
public interface GestionFacade {
/**
* Este metodo inserta un nuevo cliente en el sistema.
*
* @param cliente Cliente a insertar.
* @throws atlas.core.exceptions.ServiceException
*
Lanza atlas.core.exceptions.ServiceException ante cualquier
error producido.
*/
void insertCliente(Cliente cliente) throws ServiceException;
/**
* Este metodo obtiene un Cliente a partir de la PK.
*
* @param idCliente PK del cliente.
* @throws atlas.core.exceptions.ServiceException
*
Lanza atlas.core.exceptions.ServiceException ante cualquier error
*
* @return <code>ejpl.gestion.domain.Cliente</code> que representa el
Cliente encontrado o null en caso contrario.
*/
Cliente obtenerClientePorId(Integer idCliente) throws ServiceException;
74 de 198
Framework Atlas
Normativa
Ejemplo de implementación de una fachada
package ejpl.gestion.services.facade;
import
import
import
import
import
java.util.List;
atlas.core.exceptions.ServiceException;
org.springframework.stereotype.Service;
ejpl.gestion.domain.Cliente;
ejpl.gestion.services.ClienteService;
/* Esta clase representa la fachada del sistema.
* @author ICM
* @version 1.0
*/
@Service
public class GestionFacadeImpl implements GestionFacade {
/**
* El Servicio de Clientes
*/
private ClienteService clienteService;
/**
* Constructor sin argumentos.
*/
public GestionFacadeImpl() {
}
/**
* Este metodo inyecta el servicio ClienteService.
* @param clienteService El servicio a inyectar.
*/
public void setClienteService(ClienteService clienteService) {
this.clienteService = clienteService;
}
/**
* {@inheritDoc}
* @see
ejpl.gestion.services.facade.GestionFacade#insertCliente(ejpl.gestion.domain.Cliente)
*/
public void insertCliente(Cliente cliente) throws ServiceException {
clienteService.insertCliente(cliente);
}
/**
* {@inheritDoc}
*
* @see ejpl.gestion.services.facade.GestionFacade#obtenerClientePorId(java.lang.
* Integer)
*/
public Cliente obtenerClientePorId(Integer idCliente) throws ServiceException {
return clienteService.obtenerClientePorId(idCliente);
}
75 de 198
Framework Atlas
Normativa
6.3.2
SERVICIOS
Como ya se ha comentado anteriormente los servicios implementarán la lógica de negocio de la aplicación.
SNServiceImpl
NORMA
Para crear un servicio se crearán dos clases, con la siguiente nomenclatura:
o
<nombre>Service (Interfaz del servicio)
o
<nombre>ServiceImpl (Implementación del servicio)
Donde <nombre> debe ser sustituido por el nombre del servicio.
Estas clases se incluirán en el paquete services del bloque funcional correspondiente.
class serv ices
«interface»
ClienteService
+
+
+
+
+
+
+
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List <Cliente>
obtenerTotalClientes(Object) : int
updateCliente(Cliente) : void
NORMA
ClienteServ iceImpl
-
clienteDAO: ClienteDAO
+
+
+
+
+
+
+
+
+
ClienteServiceImpl()
deleteCliente(Cliente) : void
insertCliente(Cliente) : void
insertOrUpdateCliente(Cliente) : void
obtenerClientePorId(Integer) : Cliente
obtenerClientes(int, int, Object, Object) : List<Cliente>
obtenerTotalClientes(Object) : int
setClienteDAO(ClienteDAO) : void
updateCliente(Cliente) : void
SNAnotacion
Todos las implementaciones de los servicios deberán ir precedidos de la anotación @Service.
76 de 198
Framework Atlas
Normativa
SNMVC
NORMA
La capa de negocio debe ser totalmente independiente de la capa de presentación, es decir nunca
se accederá de manera directa desde los servicios de negocio a información de otras capas (por
ejemplo, a la sesión Http).
Toda la información requerida por los métodos de un servicio se le ha de pasar como parámetro.
Hay que tener en cuenta que cualquier servicio de negocio puede ser transformado en un servicio
web en un momento dado, y por tanto debe ser independiente.
Para facilitar la tarea de implementación de las operaciones CRUD en los Servicios, se proporciona dentro
del arquetipo una interfaz llamada BaseService y su correspondiente implementación, con los métodos
básicos ya implementados de tal forma que podemos crear nuestros servicios heredando de esta clase e
implementando solo aquellos métodos que sean específicos de nuestro servicio.
A continuación se muestra la interfaz BaseService:
package ejpl.services;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import atlas.core.exceptions.ServiceException;
import ejpl.dao.BaseDAO;
/**
* Interfaz de servicio genérico con funcionalidad CRUD
*
* <p>Extiende esta interfaz si se requiere servicios para los objetos de modelo sin
* necesidad de realizar cast de conversión de datos.
*
* @param <T> el tipo de objeto que manejará este servicio.
* @param <PK> la clave primaria del objeto de dominio.
* @param <D> el dao que maneja el objeto.
*/
public interface BaseService <T, PK extends Serializable, D extends BaseDAO<T, PK>> {
/**
* Establece el valor del DAO
* @param dao El DAO
*/
void setDao(D dao);
/**
* Devuelve el valor del DAO
* @return el DAO
*/
D getDao();
/**
* Método genérico usado para obtener todos los objetos de un tipo
* particular. Este método es equivalente a obtener todas las filas
* de una tabla.
*
77 de 198
Framework Atlas
Normativa
* <p>El número total de elementos que correspondería al método
* countAll() se puede obtener a través del método size() del objeto
* de lista devuelto.</p>
*
* @return Lista de los objetos recuperados de BD
* @throws ServiceException Error en la invocación
*/
List<T> findAll() throws ServiceException;
/**
* Método genérico usado para obtener el total de objetos de un tipo
* particular.
* @return número de elementos totales en la tabla.
* @throws ServiceException Error en la invocación
*/
Long countAll() throws ServiceException;
/**
* Obtiene todos los registros sin duplicados.
* <p>Si se utiliza este método, es imperativo que las clases de
* modelo implementen correctamente los métodos hashcode/equals.</p>
*
* <p>El número total de elementos que correspondería al método
* countAllDistinct() se puede obtener a través del método size() del
* objeto de lista devuelto.</p>
*
* @return Lista de los objetos recuperados de BD
* @throws ServiceException Error en la invocación
*/
List<T> findAllDistinct() throws ServiceException;
/**
* Obtiene en número total de registros sin duplicados.
* @return número de elementos totales sin duplicados.
* @throws ServiceException Error en la invocación
*/
Long countAllDistinct() throws ServiceException;
/**
* Método genérico para obtener un objeto basado en el tipo de clase
* y su identificador único. Si no se encuentra el objeto, este método
* devolverá null.
*
* @param id el identificador (clave primaria) del registro a obtener
* @return el objeto de base de datos recuperado
* @throws ServiceException Error en la invocación
*/
T find(PK id) throws ServiceException;
/**
* Método para obtener una serie de elementos del sistema dados unos ordenes y filtros
* @param index Indice de paginacion actual.
* @param pageSize Tamaño de pagina.
* @param orders Criterios de ordenacion
* @param filters Filtros de busqueda.
* @return <code>java.util.List</code> La lista de objetos encontrados
* @throws ServiceException Error en la invocación
*/
List<T> find(int index, int pageSize, Order[] orders,
Criterion[] filters) throws ServiceException;
/**
* Método para obtener el numero de elementos dada una serie de filtros
* @param filters Filtro de busqueda.
* @return <code>int</code> con el numero total de objetos encontrados.
* @throws ServiceException Error en la invocación
*/
int count(Criterion[] filters) throws ServiceException;
/**
* Comprueba la existencia de un objeto en base a su clave primaria.
*
* @param id el identificador de la entidad
* @return - true si el objeto existe, false en caso contrario
* @throws ServiceException Error en la invocación
*/
78 de 198
Framework Atlas
Normativa
boolean exists(PK id) throws ServiceException;
/**
* Método genérico para grabar un objeto (maneja objetos nuevos y modificados).
* Si el objeto es nuevo, este se devolverá con la clave primaria generada para
* su inserción en base de datos.
*
* @param object el objeto a guardar
* @return el objeto persistente
* @throws ServiceException Error en la invocación
*/
T insert(T object) throws ServiceException;
/**
* Método genérico para grabar un objeto (maneja objetos nuevos y modificados).
* Si el objeto es nuevo, este se devolverá con la clave primaria generada para
* su inserción en base de datos.
*
* @param object el objeto a guardar
* @throws ServiceException Error en la invocación
*/
void insertOrUpdate(T object) throws ServiceException;
/**
* Método genérico para grabar actualizar un objeto
*
* @param object el objeto a guardar
* @throws ServiceException Error en la invocación
*/
void update(T object) throws ServiceException;
/**
* Método genérico para eliminar un objeto de la base de datos en base a su
* clave primaria.
*
* @param id el identificador (clave primaria) del registro a obtener
* @throws ServiceException Error en la invocación
*/
void delete(PK id) throws ServiceException;
/**
* Método genérico para eliminar un objeto de la base de datos
*
* @param object el objeto a eliminar
* @throws ServiceException Error en la invocación
*/
void delete(T object) throws ServiceException;
/**
* Encuentra una lista de registos usando una 'named query'.
*
* @param queryName nombre de la consulta a ejecutar
* @param queryParams un objeto Map con los nombres de los parámetos y sus valores
* @return una lista con los registros encontrados
* @throws ServiceException Error en la invocación
*/
List<T> findByNamedQuery(String queryName, Map<String, Object> queryParams)
throws ServiceException;
}
La implementación de esta clase se puede ver en el paquete dao en la clase BaseServiceImpl.
PRACTICA
BUENA
ADBaseService
En el caso de que en el proyecto se identifiquen otros métodos comunes a todos los Servicios
estos métodos se incorporaran en la interfaz BaseService y en su correspondiente
implementación.
79 de 198
Framework Atlas
Normativa
La creación de nuevos servicios se realizará utilizando los mecanismos de herencia sobre la clase
BaseService. Dentro de los arquetipos se ha incluido un ejemplo de nuevo servicio que accede a la tabla
de clientes: ClienteService.
A continuación se muestra un posible código de ejemplo para las clases ClienteService y
ClienteServiceImpl, que heredan de BaseService y no añaden funcionalidad a la clase padre (pero podrían
hacerlo):
Ejemplo: ClienteService
package ejpl.services;
import ejpl.domain.Cliente;
import ejpl.dao.ClienteDAO;
/**
* Interfaz para el Servicio de la clase de dominio Cliente
* @see ejpl.Cliente
* Fecha: 20-feb-2012 15:43:54
*/
public interface ClienteService
extends BaseService<Cliente, Integer, ClienteDAO> {
}
Ejemplo: ClienteServiceImpl
package ejpl.services;
import
import
import
import
import
ejpl.domain.Cliente;
ejpl.dao.ClienteDAO;
org.springframework.stereotype.Service;
org.springframework.transaction.annotation.Propagation;
org.springframework.transaction.annotation.Transactional;
/**
* Implementación del servicio para la clase de dominio Cliente
* @see ejpl.Cliente
* Fecha: 20-feb-2012 15:43:54
*/
@Service
@Transactional (readOnly = false, propagation = Propagation.REQUIRED)
public class ClienteServiceImpl
extends BaseServiceImpl<Cliente, Integer, ClienteDAO>
implements ClienteService {
}
Nota
Los servicios se deben inyectar en el contexto de Spring en el fichero applicationContext-services.xml
80 de 198
Framework Atlas
Normativa
6.3.3
INYECCION DE DEPENDENCIAS
La fachada y los servicios se deben incluir en los ficheros de configuración de Spring. Para homogeneizar
los desarrollos se establece que los ficheros de configuración de Spring se incluyan en la carpeta
NORMA
src/main/resources/conf.
SNSpring
Los ficheros de configuración de Spring se incluirán en la carpeta src/main/resources/conf.
A continuación se muestra un ejemplo de ficheros de configuración tal y como los podemos encontrar
dentro de alguno de los arquetipos.
En el arquetipo de módulos de tipo librería en lugar de todos los ficheros anteriores solamente aparece
un fichero de configuración de Spring llamado applicationContext-yyyy.xml donde yyyy se corresponde
con el nombre de la librería. Este fichero de contexto irá incluido dentro del jar de la librería y en las
aplicaciones que utilicen esta librería, deberán referenciarlo dentro del parámetro contextConfigLocation
del fichero web.xml de las aplicaciones en las que se utilice la librería.
SNSpringLIB
NORMA
Cuando se desarrolle un módulo de tipo librería se creará un fichero de contexto con la
nomenclatura applicationContext-yyyy.xml donde yyyy se corresponde con el nombre del
módulo. Este fichero se situará en el directorio conf de la librería para que se incluya dentro del jar
de esta librería.
Este fichero será el único de esta librería que se referenciará en el parámetro
contextConfigLocation del fichero web.xml de las aplicaciones en las que se utilice la librería.
81 de 198
Framework Atlas
Normativa
SNDependencias
El fichero de configuración de Spring donde se definen los servicios y la fachada se debe llamar
NORMA
applicationContext-services.xml. En el caso de que este fichero se haga muy grande se podría
dividir en varios ficheros con la nomenclatura applicationContext-services-yyyy.xml donde yyyy es
un nombre que identifica a este fichero.
No se permite instanciar objetos de fachadas o servicios directamente.
Los módulos de tipo librería en lugar de esta norma les aplica la norma SNSpringLIB.
Los servicios de Spring se pueden construir en base a 5 ámbitos distintos de creación según las
propiedades que se le deseen otorgar, dicho ámbitos serían:
Ambito
Singleton
Descripción
Solo se creará una instancia del servicio, la cual será compartida por
“contenedor Spring”. Éste será el ámbito por defecto que adoptará Spring
cuando no se especifique ningún otro.
Prototype
Este ámbito resulta en la creación de una nueva instancia del servicio cada vez
que se realice una petición sobre el mismo.
Request
El ámbito del servicio es el mismo que el ciclo de vida de una petición
HttpRequest. Solo tiene sentido en aplicaciones web. (No se puede utilizar)
Session
El ámbito del servicio es el mismo que el ciclo de vida de una sesión Http. Solo
tiene sentido en aplicaciones web. (No se puede utilizar)
Global Session
El ámbito del servicio es el mismo que el ciclo de vida de una sesión Http
Global (Ámbito de aplicación). Solo tiene sentido en aplicaciones web. (No se
puede utilizar)
82 de 198
Framework Atlas
Normativa
SNAmbitos
NORMA
El ámbito de creación de los servicios en Spring debe ser Singleton, pudiendo crear servicios de
ámbito Prototype única y exclusivamente en ciertos casos excepcionales, totalmente justificados y
autorizados previamente por ICM.
Completando lo anterior, los ámbitos de creación en Spring denominados request, session y
global session no se pueden de utilizar bajo ninguna circunstancia.
A continuación se muestra un ejemplo de fichero de configuración de Spring de los servicios y la fachada:
applicationContext-services.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- ============================================================= -->
<!-Definicion de todos los servicios de la aplicacion
-->
<!-- ============================================================= -->
<bean id="facade" class="ejpl.gestion.services.facade.GestionFacadeImpl"
p:clienteService-ref="clienteService"/>
<!-- Aqui van los servicios propios del proyecto-->
<bean id="clienteService" class="ejpl.gestion.services.ClienteServiceImpl"
p:clienteDAO-ref="clienteDAO"/>
</beans>
PRACTICA
BUENA
SNAgrupacion
Para mejor organización de los servicios dentro del fichero de contexto de Spring se
recomienda organizarlos por bloques funcionales. De forma que por cada bloque funcional se
incluya en el fichero de configuración de Spring lo siguiente:
o
Comentario con el nombre del bloque funcional
o
Definición del bean de la fachada
o
Definición de los bean de los distintos servicios.
Esto facilitará tanto el desarrollo como el posterior mantenimiento de la aplicación.
83 de 198
Framework Atlas
Normativa
6.3.4
MANEJO DE EXCEPCIONES
Uno de los problemas con el manejo de excepciones es saber cuándo y cómo utilizarlas.
En términos generales, las aplicaciones desarrolladas con el framework Atlas tendrán que ser capaces de
manejar dos tipos de excepciones:
·
Excepciones de negocio: Serán aquellas excepciones creadas a medida por el desarrollador.
Estas excepciones permiten representar aquellos errores inherentes al negocio. Serán lanzadas y
gestionas por el propio programador, indicando así el incumplimiento de una regla del negocio.
·
Excepciones del sistema: En este grupo se engloban todas aquellas excepciones producidas de
forma automática por el entorno. Serán excepciones propietarias del API, como por ejemplo, un
fallo en la conexión a una base de datos, fallo de invocación a un servicio web, etc.
Dentro de Atlas para normalizar el uso de excepciones se ha creado la clase ServiceException. Con esta
clase lo que se pretende es que todas las excepciones que se generen en la capa de negocio y se
NORMA
propaguen a la capa de presentación sean de tipo ServiceException.
SNThrowsException
Todos los métodos de los servicios y de la fachada sólo pueden lanzar excepciones del tipo
ServiceException o clases que hereden de ella.
Ejemplo de excepción devuelta por un método
void deleteCliente(Cliente cliente) throws ServiceException;
Si en nuestra aplicación queremos crear excepciones propias del negocio las podemos crear heredando de
la clase ServiceExcepcion.
NORMA
SNCustomException
Cuando se desee implementar una excepción propia del negocio, esto es a medida, se deberá
extender de la clase “ServiceException”.
El nombre de la excepción será <nombre>ServiceException y se ubicará en el paquete exceptions
del bloque funcional correspondiente.
Ejemplo de excepción propia del negocio
package ejpl.gestion.exceptions;
84 de 198
Framework Atlas
Normativa
public class InvalidAccountServiceException extends ServiceException {
private static final long serialVersionUID = -3193946292701856020L;
public InvalidAccountServiceException() {
super();
}
public InvalidAccountServiceException(String message) {
super(message);
}
}
PRACTICA
BUENA
SNExcComunes
Las excepciones que puedan ser comunes a varios bloques funcionales se pueden ubicar en el
paquete exceptions de un bloque funcional común.
NORMA
Estas excepciones podrán ser utilizadas desde los otros bloques funcionales.
SNNegocioException
Cuando se lance una excepción propia del negocio, se deberá atrapar en el momento de
producirse para encapsularla en otra de tipo “ServiceException”.
Ejemplo de relanzado de excepciones de negocio
Public void reserveRoom(Integer customerId, String account, Date expDate)
throws InvalidAccountServiceException, RoomAvailabilityServiceException
if (customerManager.setReserve(customerId, account, expDate)
.booleanValue()) {
Room room = hotelManager.getFirstAvailableRoom();
if (room != null) {
LOG.debug("getFirstAvailableRoom(): " + room.getRoomNumber());
Customer customer = customerManager.getCustomer(customerId);
room.setReserveStatus(Room.OCUPPIED);
room.setCustomer(customer);
.....
} else {
throw new RoomAvailabilityServiceException();
}
} else {
throw new InvalidAccountServiceException();
}
}
85 de 198
{
Framework Atlas
NORMA
Normativa
SNSystemException
Cuando se lance una excepción que no sea del negocio, se deberá atrapar en el momento de
producirse para encapsularla en otra de tipo “ServiceException”.
Ejemplo de relanzado de excepciones de Sistema
Public Boolean setReserve(Integer customerId, String sAccount,
Date dExpiredDate) throws ServiceException {
Boolean reserve = false;
try {
reserve = webService.checkAccount(customerId, sAccount,
dExpiredDate);
} catch (AxisFault axisex) {
throw new ServiceException(axisex);
} catch (JmsException jmsex) {
throw new ServiceException(jmsex);
}
return reserve;
SNDAOException
Los servicios que invoquen de forma directa a los componentes de la capa de acceso a datos
NORMA
(formada por Spring-DAOs), deberán atrapar y gestionar las excepciones del tipo
“DataAccessException” que se lancen, con objeto de encapsularlas y relanzarlas como
excepciones de tipo “ServiceException”, ya sea a la fachada u otros servicios de más alto nivel.
La capa de acceso a datos no hará ningún de tratamiento de las excepciones producidas,
simplemente se limitará a lanzarlas a la capa de negocio para que sea esta la encargada de
manejarlas.
Ejemplo de captura de excepciones de la capa de acceso a datos
public void deleteCliente(Cliente cliente) throws ServiceException {
try {
this.clienteDAO.deleteCliente(cliente);
} catch (DataAccessException dae) {
throw new ServiceException(dae);
}
}
86 de 198
Framework Atlas
Normativa
6.3.5
TRANSACCIONALIDAD
Una de funcionalidades más importantes aportadas por el framework Spring es la gestión de la
transaccionalidad proporcionando una capa de abstracción hacia el gestor transaccional utilizado,
aportando los siguientes beneficios:
·
Proporciona un modelo de programación consistente entre diferentes APIs transaccionales tales
como JTA, JDBC, Hibernate, JPA y JDO.
·
Soporte a gestión declarativa de transacción.
·
Totalmente integrado con la abstracción de acceso a datos de Spring.
·
Proporciona un API para la gestión programática de transacciones más sencilla que las habituales.
·
Permite gestión de transacciones mediante anotaciones aplicadas a cualquier clase, y no a clases
especiales como EJBs.
·
Ofrece reglas de rollback mediante anotaciones, de forma que se puede configurar el rollback
automático de una transacción en caso de producirse cierto tipo de excepción. Esta característica
no existe en el modelo de EJB. Spring permite adaptar el comportamiento de las transacciones,
mediante AOP, por ejemplo para insertar un comportamiento personalizado en rollback de
transacciones.
·
A diferencia del modelo de EJB CMT, el cual esta ligado a JTA, la transacción anotacional de
Spring trabaja en cualquier entorno.
El modelo declarativo de Spring se basa en el soporte de proxies AOP y metadatos (XML o anotaciones
solo soportadas por entornos J2SE 5 o superiores). Esta combinación de proxies y metadatos permite
tener proxies AOP que usan un TransactionInterceptor en conjunción con el PlatformTransactionManager
apropiado y gestionar las transacciones en la ejecución de métodos. El modelo transaccional de Spring se
puede resumir en la siguiente figura:
87 de 198
Framework Atlas
Normativa
El modelo que se deberá seguir es el basado en anotaciones. En los servicios de Spring, se usará
@Transaction la cual posee un conjunto de atributos que permitirán definir las reglas y políticas para
aplicar sobre métodos. En concreto, podremos tener uno o más parámetros como los siguientes:
6.3.5.1
Propagation:
Es utilizado para especificar los límites de una transacción. Gracias a esta característica tendremos
bastantes opciones para especificar comportamiento si un método transaccional es ejecutado cuando un
contexto transaccional ya existe: Por ejemplo, podríamos ejecutar algo en la transacción en ejecución;
suspender la transacción ejecución y crear una nueva transacción, etc.
El catálogo de atributos transaccionales disponibles para Spring es:
Propagation
PROPAGATION_REQUIRED
Descripción
Se ejecuta en la actual transacción. Si no existe, se crea una
nueva.
PROPAGATION_REQUIRES_NEW
Siempre se crear una transacción nueva. Si existe una
transacción previa se suspende.
PROPAGATION_SUPPORTS
Si existe una transacción se ejecuta en la misma transacción.
Si no existe una transacción se ejecutará sin contexto
transaccional.
PROPAGATION_NOT_SUPPORTED Se ejecuta sin contexto transaccional. Si existe una transacción
se detiene.
PROPAGATION_MANDATORY
Se ejecuta en la actual transacción. Si no existe una
transacción previa, se produce una excepción.
PROPAGATION_NEVER
Se ejecuta sin contexto transaccional. Si existe una transacción
previa se produce una excepción.
PROPAGATION_NESTED
Se ejecuta en una transacción anidada si existe una
transacción
previa.
En
caso
contrario
se
comporta
exactamente igual que REQUIRED. Se debe tener cuidado al
utilizar este atributo transaccional, debido a q solo es
soportado por algunos gestores de transacciones.
6.3.5.2
Isolation Level:
Con este atributo podremos indicar el control de concurrencia. Cuando múltiples transacciones se están
ejecutando en paralelo se pueden dar “dirty reads”, “non repeateable reads” y “phantom reads”.
88 de 198
Framework Atlas
Normativa
El estándar ANSI/ISO SQL define cuatro niveles de aislamiento transaccional en función de tres hechos
que deben ser tenidos en cuenta entre transacciones concurrentes. Estos hechos no deseados son:
· Dirty read (lecturas sucias): Una transacción lee datos escritos por una transacción no esperada y
no cursada (no ha hecho todavía el commit).
· Non-repeateable read (lecturas no repetibles): Una transacción vuelve a leer datos que
previamente había leído y encuentra que han sido modificados por una transacción cursada.
· Phantom read (lectura fantasma): Una transacción vuelve a ejecutar una consulta, devolviendo un
conjuto de filas que satisfacen una condición de búsqueda y encuentra que otras filas que
satisfacen la condición han sido insertadas por otra transacción cursada.
Así, el framework Spring nos proporciona un conjunto de niveles de aislamiento que podremos usar en
base a la tolerancia del sistema:
Isolation level
Descripción
Usa la política de aislamiento por defecto del
ISOLATION_DEFAULT
sistema persistente.
ISOLATION_READ_UNCOMMITTED
Permite leer datos incluso cuando existan filas sin
commit, esto podría causar dirty read, non
repeteable read o phantom reads.
Previenen lecturas dirty pero todavía se pueden dar
ISOLATION_READ_COMMITTED
lecturas non-repeateable o lecturas phantom.
ISOLATION_REPEATABLE_READ
Previene lecturas dirty y non-repeateable pero se
pueden dar lecturas phantom.
Este nivel consigue ACID (Atomicity, concurrancy,
ISOLATION_SERIALIZABLE
isolation and durability). Pero al ser tan estricto
puede causar problemas de rendimiento.
6.3.5.3
Read Only:
En algunas ocasiones hay un requerimiento que es solo leer datos de la base de datos, en dichos casos
utilizar este atributo puede proporcionar un buen rendimiento ya que la base de datos aplicará algunas
optimizaciones. Esto solo puede ser hecho cuando una nueva transacción es arrancada en operaciones de
tipo
“select”,
así
este
atributo
solo
tomará
sentido
si
la
propiedad
de
propagación
PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW, o PROPAGATION_NESTED.
89 de 198
es
Framework Atlas
Normativa
6.3.5.4
TimeOut:
Se utiliza para prevenir deadlocks o recursos bloqueados en el sistema. Permite especificar un timeout que
“matará” la transacción después del periodo especificado. Al igual que en el caso anterior este atributo solo
tomará
sentido
si
la
propiedad
de
propagación
es
PROPAGATION_REQUIRED,
PROPAGATION_REQUIRES_NEW, o PROPAGATION_NESTED.
A continuación se muestra un ejemplo que muestra como se deben implementar las transacciones
mediante anotaciones.
El servicio que se desea hacer transaccional:
Ejemplo de servicio transaccional
// La implementación del servicio transaccional
package ejpl.gestion.services;
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class RoomServiceImpl implements RoomService {
public Room getRoom(String roomName) {
throw new ServiceException();
}
public Room getRoom(String roomName, Integer idRoom) {
throw new ServiceException();
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void insertRoom(Room room) {
throw new ServiceException();
}
@Transactional(readOnly = false)
public void updateRoom(Room room) {
throw new ServiceException();
}
}
Según el ejemplo anterior se puede definir atributos transaccionales a nivel de clase, de esta manera
modelamos el comportamiento transaccional que por defecto tendrá cada uno de los métodos de la misma.
A partir de ahí, se podrá sobrescribir dicho comportamiento transaccional por defecto, utilizando la
anotación @Transaction sobre el método que se desee modificar. Los métodos getRoom se ejecutarán en
un contexto de solo lectura con soporte a transacción, el método insertRoom en un contexto de lecturaescritura con transacción requerida y el método updateRoom en un contexto de lectura-escritura con
soporte a transacción.
90 de 198
Framework Atlas
Normativa
PRACTICA
BUENA
SNGenericTransaction
Si bien es cierto que el manejo de transacciones dependerá del negocio, en la mayoría de los
casos las transacciones se podrán configurar tal y como se han expuesto en el ejemplo anterior
por lo que se recomienda utilizar esta configuración por defecto a la hora de gestionar
transacciones en los servicios de negocio.
La gestión de las transacciones siempre deberá realizarse a nivel de la capa de servicios, nunca a nivel de
la capa DAO. Se recomienda gestionar transacciones en la fachada por ser el punto de control de la capa
de servicios.
Desde un punto vista de la configuración, lo primero que se debe hacer es indicar el gestor transaccional
que se quiere utilizar, en el caso del framework Atlas lo configuramos para utilizar Hibernate como gestor
transaccional. Esta configuración ya viene preconfigurada en los arquetipos en el fichero
applicationContext-database.xml y no se debe modificar.
A continuación se muestra como se ha configurado el gestor de transacciones en los arquetipos:
Configuración del gestor de transacciones en applicationContext-database.xml
<!-- ========= CONFIGURACION DEL TRANSACTION MANAGER ===================== -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"
p:entityInterceptor-ref="atlasInterceptor"/>
NORMA
NORMA
<!-- ==== GESTION DE TRANSACCIONES MEDIANTE ANOTACIONES ============== -->
<tx:annotation-driven transaction-manager="transactionManager"/>
SNTransactionAnnotated
Para el manejo de transacciones se empleará el modelo de anotaciones propuesto por Spring.
SNTransactionDefault
No esta permitido modificar los atributos “Isolation Level” y “TimeOut” respecto a sus valores por
defecto. En caso de tener que alterarlo solo se podrá hacer previa autorización por parte de ICM.
91 de 198
Framework Atlas
Normativa
La manera más sencilla de indicar a Spring que una transacción necesita hacer rollback será lanzar una
excepción desde el código que se está ejecutando dentro del contexto transaccional. Spring atrapará
cualquier excepción no manejada y marcará la transacción para rollback.
SNTransactionRollback
NORMA
Se utilizará el mecanismo de rollback de transacción basado en anotaciones. Esto se conseguirá
mediante la anotación @Transaction y los atributos “rollbackFor”, “rollbackForClassName”,
“noRollbackFor”, “noRollbackForClassName”. Esto solo tendrá sentido para las excepciones de
negocio gestionadas en la capa de servicios ya que las excepciones de tipo
“DataAccessException” a nivel de DAO o “RuntimeException” se traducirán en un rollback
automático.
Por ejemplo, el código necesario para realizar un rollback de una transacción cuando se lance una
excepción de negocio de tipo “NotRoomFoundServiceException” podría ser algo como:
Ejemplo de definición de rollback
@Transactional(readOnly = false,
propagation = Propagation.REQUIRED,
rollbackForClassName = {"NotRoomFoundServiceException"})
Atención
Si desde un método de un Servicio se invoca a otro método del mismo Servicio el contexto transaccional
será el de la anotación transaccional del primero, y la anotación transaccional del segundo método será
ignorada. Por lo tanto la invocación del segundo método siempre participará en la transacción del primero,
y en ningún caso se creará una nueva transacción aunque se le indique mediante una anotación.
6.3.6
.
FICHEROS TEMPORALES
En algunas aplicaciones es necesario generar ficheros temporales en un directorio del entorno.
Actualmente todos los entornos ya tienen preparados estos directorios y están compartidos por NFS entre
las distintas máquinas del cluster. Las aplicaciones podrán acceder a estos directorios para dejar y eliminar
ficheros pero no podrán crear carpetas dentro de estos directorios.
Existen jobs periódicos que se
encargan de limpiar estos directorios, para eliminar los ficheros temporales obsoletos.
La ruta de los directorios temporales en los entornos de ICM está configurada utilizando la propiedad del
sistema java.io.tmpdir. El framework Atlas ya establece el valor para esta propiedad dependiendo del
92 de 198
Framework Atlas
Normativa
entorno en el que nos encontremos (no es responsabilidad de la aplicación). En entornos locales (la
máquina local del desarrollador) la ruta será la que esté establecida por defecto en el sistema operativo.
A continuación se muestran dos ejemplos de creación de ficheros temporales:
Creación de un fichero temporal a partir de un byte[]
public File guardarFicheroTemporal(byte[] b) throws ServiceException {
File temp = null;
try {
temp = File.createTempFile("EJPL_", ".txt");
temp.deleteOnExit(); //Eliminar fichero al finalizar la ejecución de la JVM.
if (b != null) {
FileOutputStream fout = new FileOutputStream(temp);
fout.write(b);
fout.flush();
fout.close();
}
logger.info("--- Nombre fichero: " + temp.getName());
} catch (IOException e) {
logger.error("Error al crear el fichero");
throw new ServiceException(e);
}
return temp;
}
Creación de un fichero temporal rellenando su contenido
//crear fichero en el directorio temporal
try {
//Creacion de fichero temporal
// mas info:
http://download.oracle.com/javase/1,5.0/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String)
File temp = File.createTempFile("EJPL_", ".txt");
temp.deleteOnExit(); //Eliminar fichero al finalizar la ejecución de la JVM.
FileOutputStream fout = new FileOutputStream(temp);
PrintStream out = new PrintStream(fout);
out.println("Ejemplo fichero en el directorio temporal."); //Escribimos dentro del fichero
logger.info("--- Nombre fichero: " + temp.getName());
} catch (IOException e) {
logger.error("Error al crear el fichero");
throw new ServiceException(e);
}
93 de 198
Framework Atlas
Normativa
SNFicherosTemporales
Si se necesita crear un fichero temporal, se utilizarán los métodos que proporciona la clase
NORMA
java.io.File para ello (File.createTempFile).
Al utilizar estos métodos, los ficheros temporales se crearán en el directorio definido por la
propiedad del sistema java.io.tmpdir. El valor de esta propiedad ya está preestablecido en el
framework Atlas dependiendo del entorno en el que se encuentre desplegada la aplicación, por lo
que no se debe modificar su valor desde el código fuente de ninguna aplicación.
PRACTICA
BUENA
SNNomFicheroTemporal
En aquellos casos en los que los ficheros se generan en cada petición es necesario crear un
nombre aleatorio para el nombre del fichero para evitar que una petición sobreescriba el fichero
generado por otra.
Dado que el directorio temporal es compartido por todas las aplicaciones se recomienda que el
nombre del fichero comience por el nombre del proyecto. Ejemplo; EJPL_<nombrealeatorio>.
6.4
ACCESO A DATOS
El acceso a datos es una de las partes con mayor índice de criticidad que pueda existir en cualquier
aplicación web.
Para el acceso a los distintos sistemas relacionales la tecnología seleccionada es Hibernate.
A continuación se muestra un diagrama general de la capa de acceso a datos desde el punto de vista de
arquitectura del sistema.
Fachada
POJO Services
POJOs
Capa de Acceso a Datos
POJO Services
POJOs
Capa de Acceso a Datos
SPRING
HibernateDaoSupport
SPRING
SPRING
Hibernate
SPRING
HibernateDaoSupport
DAO Hibernate
BD
Template
SPRING
Hibernate
Template
Arquitectura de la capa de Acceso a Datos
94 de 198
HIBERNATE
HIBERNATE
(Oracle,
etc)
Framework Atlas
Normativa
Para el acceso a la información se utilizará la solución ORM (Object-Relational Mapping) de Hibernate, la
cual se erige como un potente mapeador objeto/relacional y servicio de consultas para Java.
Hibernate permite desarrollar clases persistentes a partir de clases comunes, incluyendo asociación,
herencia, polimorfismo, composición y colecciones de objetos. El lenguaje de consultas de Hibernate HQL
(Hibernate Query Language), diseñado como una mínima extensión orientada a objetos de SQL,
proporciona un puente elegante entre los mundos de objetos y relacional. Hibernate también permite
expresar consultas utilizando SQL nativo o consultas basadas en criterios.
Soporta todos los sistemas gestores de bases de datos SQL y se integra de manera sencilla y sin
restricciones con prácticamente la totalidad de servidores de aplicaciones JEE y contenedores web,
además de poder utilizarse en aplicaciones standalone.
Se pueden enumerar las siguientes características clave:
o
Persistencia transparente: Hibernate puede operar proporcionando persistencia de una manera
transparente para el desarrollador.
o
Modelo de programación natural: Hibernate soporta el paradigma de orientación a objetos de una
manera natural: herencia, polimorfismo, composición y el framework de colecciones de Java.
o
Soporte para modelos de objetos con una granularidad muy fina: Permite una gran variedad de
mapeos para colecciones y objetos dependientes.
o
Sin necesidad de mejorar el código compilado (bytecode): No es necesaria la generación de
código ni el procesamiento del bytecode en el proceso de compilación.
o
Escalabilidad extrema: Hibernate posee un alto rendimiento, tiene una caché de dos niveles y
puede ser usado en un cluster. Permite inicialización perezosa (lazy) de objetos y colecciones.
o
Lenguaje de consultas HQL: Este lenguaje proporciona una independencia del SQL de cada base
de datos, tanto para el almacenamiento de objetos como para su recuperación.
o
Soporte para transacciones de aplicación: Hibernate soporta transacciones largas (aquellas que
requieren la interacción con el usuario durante su ejecución) y gestiona la política optimistic locking
automáticamente.
o
Generación automática de claves primarias: Soporta los diversos tipos de generación de
identificadores que proporcionan los sistemas gestores de bases de datos (secuencias, columnas
autoincrementales,...) así como generación independiente de la base de datos, incluyendo
identificadores asignados por la aplicación o claves compuestas.
95 de 198
Framework Atlas
Normativa
ADHibernate
La gestión de persistencia sobre los datos almacenados en bases de datos relacionales se
realizará utilizando el motor de persistencia Hibernate.
NORMA
El mecanismo elegido para realizar el mapeo de clases java a tablas de la base de datos será el
basado en anotaciones, dichas anotaciones proporcionarán a Hibernate la información suficiente
para saber cómo cargar y almacenar clases persistentes y se marcarán a nivel de atributo.
Se deberán utilizar aquellas anotaciones proporcionadas por Hibernate y que formen parte del
estándar JPA.
En ocasiones es posible que sea necesario utilizar anotaciones propias de Hibernate no
correspondientes al estándar JPA. Sólo se podrán utilizar si se ha consensuado previamente con
ICM y se ha otorgado una autorización excepcional para ello.
96 de 198
Framework Atlas
Normativa
6.4.1
Datasource y Sesiones de Hibernate
Todas las aplicaciones definirán un datasource para conectarse con la base de datos.
NORMA
DAODatasource
En los arquetipos ya viene configurado el datasource de acceso a base de datos. Deberá
utilizarse dicho datasource y nunca obtener directamente las conexiones jdbc.
El acceso al datasource siempre se realizará a través de la sesión de Hibernate.
La sesión en Hibernate representa la interfaz entre la aplicación Java e Hibernate. Dicha sesión permitirá
realizar operaciones de creación, modificación, lectura y eliminación de instaciones mapeadas con la base
de datos.
Históricamente, la gestión de sesiones en Hibernate se ha considerado uno de los problemas más
comunes que se encuentran en aplicaciones Web, para evitar esto han surgido un conjunto de buenas
prácticas y/o patrones que nos indican como trabajar de forma optima, en base al entorno de trabajo
establecido. De tal forma para entornos Web el modelo recomendado siempre será el patrón session-perview (Sesión por vista).
En una sesión por vista, la sesión de Hibernate se mantiene abierta mientras dura el ciclo de vida de una
petición Http.
NORMA
DAOSession
En las aplicaciones Web se deberá utilizar el patrón session-per-view, para ello Spring
proporciona un filtro que se encargará de tratar toda la problemática asociada a la gestión de
sesiones Hibernate en cada petición.
Este filtro ya se encuentra definido en el fichero web.xml y no se puede modificar.
DAOFlushing
Se deberá usar el mecanismo de flushing por defecto en Hibernate sobre las sesiones, esto es
NORMA
el denominado FlushMode.AUTO. Este valor por defecto deberán ser válidos para cualquier
entorno. Solo se podrá optar por otra estrategia, previo consenso con ICM.
Se deberá usar el mecanismo de fetching por defecto en Hibernate, este es lazy select
fetching para colecciones y lazy proxy fetching para asociaciones single-valued. Estos valores por
defecto deberán ser válidos para cualquier entorno. Solo se podrá optar por otra estrategia, previo
consenso con ICM.
97 de 198
Framework Atlas
Normativa
6.4.2
Configuración
A continuación se muestran los distintos ficheros donde se encuentra la configuración de la capa de
acceso a datos.
6.4.2.1
enviroment.properties
El fichero enviroment.properties contiene las variables que dependen del entorno por lo tanto aquí es
donde se tiene que configurar el datasource.
A continuación se muestra la configuración del datasource que viene configurada en los arquetipos.
environment.properties
######################################################
# Fichero de variables de configuración específicas #
# para el entorno LOCAL
#
######################################################
# Configuracion para acceso a base de datos
dataSourceName=${artifactId}-webDS
jdbc.driverClassName=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@icm21.icm.es:1521:denivel2
jdbc.username=dba_ejpl
jdbc.password=sis
hibernate.dialect=org.hibernate.dialect.Oracle9iDialect
Nota
Para más información sobre el fichero de configuración environment.properties consultar el manual de
arquetipos.
6.4.2.2
applicationContext-database.xml
El fichero applicationContext-database.xml que incorpora el arquetipo contiene la configuración de todos
los parámetros de conexión a base de datos, incluyendo el sessionFactory y el transactionManager.
En este fichero solamente se puede modificar la propiedad packagesToScan para incorporar los paquetes
donde residen las distintas clases de dominio que sea necesario crear (solo es necesario incluir los
paquetes raíz, los subpaquetes serán escaneados automáticamente).
applicationContext-database.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================== -->
<!-En este fichero se configuran todos los
-->
<!-parametros de conexion a la base de datos
-->
<!-incluyendo el sessionFactory y el transactionManager
-->
<!-- ============================================================== -->
<beans xmlns="http://www.springframework.org/schema/beans"
98 de 198
Framework Atlas
Normativa
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- =========== CONFIGURACION DE CONEXIONES PARA ACCESO A DATOS =========== -->
<!-- DataSource Definition -->
<!-- via JNDI definido en el contenedor de aplicaciones -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/${dataSourceName}" />
</bean>
<!-- ============ CONFIGURACION DEL SESSIONFACTORY DE HIBERNATE ======== -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<description>
Bean que representa a la factoria de hibernate para crear
sesiones con base de datos
</description>
<!-- Descomentar para auditoria
<property name="configurationClass"
value="atlas.audit.hibernate.cfg.AnnotationConfiguration" />
-->
<property name="schemaUpdate" value="false"/>
<property name="packagesToScan">
<list>
<!-- ======== INCLUIR AQUI TODOS LOS PAQUETES DE CLASES ANOTADAS ===== -->
<value>ejpl.bloquefuncionaln.domain</value>
<!-- Necesario si se quiere utilizar el componente de calendario -->
<value>atlas.componentes.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<!-- La No se permite el uso de cachés de segundo nivel en Hibernate.
En el caso de que se justifique su uso se solicitará una
autorización excepcional a ICM. -->
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<!-- Descomentar para auditoria
<prop key="atlas.audit.triggers">false</prop>
<prop key="atlas.audit.console_output">false</prop>
-->
99 de 198
Framework Atlas
Normativa
</props>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<!-- ============ CONFIGURACION DEL TRANSACTION MANAGER =========== -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" p:entityInterceptorref="atlasInterceptor"/>
<!-- ========== GESTION DE TRANSACCIONES MEDIANTE ANOTACIONES ============ -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- ========== TRADUCTOR DE EXCEPCIONES DE SPRING ============ -->
<bean id="jdbcExceptionTranslator"
class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
<description>
Bean que representa al traductor de codigos de error SQL a excepciones JAVA
</description>
<property name="dataSource" ref="dataSource" />
</bean>
<!-- ======== DEFINICION DE HIBERNATETEMPLATE CON PROPIEDADES ========= -->
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<description>
Bean que representa la plantilla de hibernate. A este bean
se le inyectan la factoria de sesiones y el traductor de sesiones JDBC
</description>
<property name="sessionFactory" ref="sessionFactory" />
<property name="jdbcExceptionTranslator" ref="jdbcExceptionTranslator" />
</bean>
<!-- ===== DEFINICION DE BEAN auditConstants NECESARIO PARA AUDITORIA ===== -->
<!-- Descomentar para auditoria
<bean id="auditConstants" class="atlas.audit.properties.AuditConstants">
<property name="codAplicacion"
value="ejpl"/>
<property name="cdtpaccesoLogico" value="I"/>
</bean>
-->
</beans>
6.4.2.3
applicationContext-dao.xml
El fichero applicationContext-dao.xml contiene la definición de los bean de los distintos DAOs en el
contexto de Spring.
applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
100 de 198
Framework Atlas
Normativa
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- ============================================================ -->
<!-Definicion de todos los DAO`s de la aplicacion
-->
<!-- ============================================================ -->
<bean id="clienteDAO" class="ejpl.gestion.dao.ClienteDAOImpl"
p:sessionFactory-ref="sessionFactory"/>
</beans>
El ámbito de creación de los DAOs será siempre el que adopta Spring por defecto, es decir Singleton. (por
defecto si no se indica en el fichero de configuración)
DAODependencias
El fichero de configuración de Spring donde se definen los daos se debe llamar
NORMA
applicationContext-dao.xml. En el caso de que este fichero se haga muy grande se podría
dividir en varios ficheros con la nomenclatura applicationContext-dao-yyyy.xml donde yyyy es un
nombre que identifica a este fichero.
No se permite instanciar objetos de daos directamente.
Los módulos de tipo librería en lugar de esta norma les aplica la norma SNSpringLIB.
101 de 198
Framework Atlas
Normativa
6.4.3
Entidades de dominio
Las entidades de dominio son las clases Java que tienen una correspondencia con tablas del modelo de
datos relacional.
ADEntityImpl
Las clases de dominio se incluirán en el paquete domain del bloque funcional correspondiente.
No tendrán una nomenclatura específica ya que su nombre debe representar al objeto de dominio
que implemente.
NORMA
Las clases de dominio deben:
o
Incluir la anotación @Entity
o
Implementar la interface Serializable.
o
Incluir atributos privados y sus correspondientes setter y getter
o
Incluir un constructor sin argumentos
o
Implementar los métodos equals y hashcode para las entidades persistentes, ya que
dichos métodos se harán indispensables en casos como:
o
Se necesitan almacenar instancias en un conjunto (Asociaciones 1-n).
o
Se quieren utilizar las instancias como keys para un map.
o
Se quieren usar métodos de colecciones como contains(), remove(), etc…
PRACTICA
. BUENA
ADRendimiento
Hibernate puede ser una herramienta muy potente pero a su vez su utilización sin tener en
cuenta la forma en la que trabaja Hibernate puede provocar problemas de rendimiento.
Se debe evitar que el acceso a determinados datos suponga la carga en memoria de
estructuras complejas o de demasiada información que en la mayoría de los casos no se va a
necesitar.
A continuación se muestra un fragmento de la clase denominada “Cliente”, la cual representa una entidad
persistente gestionada por el motor de Hibernate:
Cliente.java
package ejpl.gestion.domain;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
102 de 198
Framework Atlas
Normativa
import
import
import
import
import
import
import
import
import
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.JoinColumn;
javax.persistence.ManyToOne;
javax.persistence.SequenceGenerator;
javax.persistence.Table;
javax.persistence.Temporal;
javax.persistence.TemporalType;
javax.persistence.GeneratedValue;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Cliente
* @author ICM
* @version 1.0.
*/
@Entity
@Table(name = "EJPL_CLIENTES")
public class Cliente implements java.io.Serializable {
/**
* Identificador del numero de serie para serializacion
*/
private static final long serialVersionUID = 1L;
/**
* Representa el identificador/PK del cliente.
*/
private Integer idCliente;
/**
* Representa el nombre del cliente.
*/
private String nombre;
/**
* Representa el primer apellido del cliente.
*/
private String apellido1;
/**
* Representa el segundo apellido del cliente.
*/
private String apellido2;
/**
* Representa la direccion del cliente.
*/
private String direccion;
/**
* Representa el telefono del cliente.
*/
private String telefono;
/**
* Representa la fecha de nacimiento del cliente.
103 de 198
Framework Atlas
Normativa
*/
private Date fechaNacimiento;
/**
* Representa el estado civil del cliente.
*/
private EstadoCivil estadoCivil;
/**
* Constructor sin argumentos.
*/
public Cliente() {
}
/**
* Constructor para la entidad Cliente con los parametros minimos.
* @param idCliente Identificador
* @param nombre Nombre
* @param apellido1 Primer Apellido
* @param apellido2 Segundo Apelillido
*/
public Cliente(Integer idCliente, String nombre, String apellido1,
String apellido2) {
this.idCliente = idCliente;
this.nombre = nombre;
this.apellido1 = apellido1;
this.apellido2 = apellido2;
}
/**
* Constructor para la entidad Cliente con los todos parametros posibles.
* @param idCliente Identificador
* @param nombre Nombre
* @param apellido1 Primer Apellido
* @param apellido2 Segundo Apelillido
* @param direccion Direccion
* @param telefono Telefono
* @param fechaNacimiento Fecha de Nacimiento
* @param estadoCivil Estado Civil
*/
public Cliente(Integer idCliente, String nombre, String apellido1,
String apellido2, String direccion, String telefono,
Date fechaNacimiento, EstadoCivil estadoCivil) {
this.idCliente = idCliente;
this.nombre = nombre;
this.apellido1 = apellido1;
this.apellido2 = apellido2;
this.direccion = direccion;
this.telefono = telefono;
this.fechaNacimiento = fechaNacimiento;
this.estadoCivil = estadoCivil;
}
/**
* @return <code>java.lang.Integer</code> Devuelve el identificador/PK de
la entidad Cliente.
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator =
"EJPL_SECUENCIA_ID_CLIENTE")
@SequenceGenerator(name = "EJPL_SECUENCIA_ID_CLIENTE",
sequenceName = "EJPL_SECUENCIA_ID_CLIENTE")
104 de 198
Framework Atlas
Normativa
@Column(name = "ID_CLIENTE", unique = true, nullable = false, precision =
9, scale = 0)
public Integer getIdCliente() {
return this.idCliente;
}
/**
* @param idCliente Modifica el identificador/PK del cliente.
*/
public void setIdCliente(Integer idCliente) {
this.idCliente = idCliente;
}
/**
* @return <code>java.lang.String</code> Devuelve el nombre del cliente.
*/
@Column(name = "NOMBRE", nullable = false, length = 50)
public String getNombre() {
return this.nombre;
}
/**
* @param nombre Modifica el nombre del cliente.
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* @return <code>java.lang.String</code> Devuelve el primer apellido del
cliente.
*/
@Column(name = "APELLIDO1", nullable = false, length = 50)
public String getApellido1() {
return this.apellido1;
}
/**
* @param apellido1 Modifica el primer apellido del cliente.
*/
public void setApellido1(String apellido1) {
this.apellido1 = apellido1;
}
/**
* @return <code>java.lang.String</code> Devuelve el segundo apellido del
cliente.
*/
@Column(name = "APELLIDO2", nullable = false, length = 50)
public String getApellido2() {
return this.apellido2;
}
/**
* @param apellido2 Modifica el segundo apellido del cliente.
*/
public void setApellido2(String apellido2) {
this.apellido2 = apellido2;
}
/**
105 de 198
Framework Atlas
Normativa
* @return <code>java.lang.String</code> Devuelve la direccion del
cliente.
*/
@Column(name = "DIRECCION", length = 100)
public String getDireccion() {
return this.direccion;
}
/**
* @param direccion Modifica la direccion del cliente.
*/
public void setDireccion(String direccion) {
this.direccion = direccion;
}
/**
* @return <code>java.lang.String</code> Devuelve el telefono del cliente.
*/
@Column(name = "TELEFONO", length = 15)
public String getTelefono() {
return this.telefono;
}
/**
* @param telefono Modifica el telefono del cliente.
*/
public void setTelefono(String telefono) {
this.telefono = telefono;
}
/**
* @return <code>java.lang.String</code> Devuelve el estado civil del
cliente.
*/
@ManyToOne
@JoinColumn(name = "FK_ESTADO_CIVIL")
public EstadoCivil getEstadoCivil() {
return this.estadoCivil;
}
/**
* @param estadoCivil Modifica el estado civil del cliente.
*/
public void setEstadoCivil(EstadoCivil estadoCivil) {
this.estadoCivil = estadoCivil;
}
/**
* @return <code>java.util.Date</code> Devuelve la fecha de nacimiento del
cliente.
*/
@Temporal(TemporalType.DATE)
@Column(name = "FC_NACIMIENTO", length = 7)
public Date getFechaNacimiento() {
return this.fechaNacimiento;
}
/**
* @param fechaNacimiento Modifica la fecha de nacimiento del cliente.
*/
public void setFechaNacimiento(Date fechaNacimiento) {
106 de 198
Framework Atlas
Normativa
this.fechaNacimiento = fechaNacimiento;
}
/**
* Implementación de hashCode para uso de Hibernate. La 'business key' en
* este caso se compondrá por [nombre, apellido1, apellido2 y
* fechaNacimiento].
*
* <p>Más info en: {@link http://community.jboss.org/docs/DOC-13933}
*/
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(this.nombre)
.append(this.apellido1)
.append(this.apellido2)
.append(this.fechaNacimiento)
.toHashCode();
}
/**
* Implementación de método equals para uso con Hibernate. Se ha definido
* la clave de negocio o 'business key' como
* [nombre, apellido1, apellido2, fechaNacimiento]
*
* <p>Más info en: {@link http://community.jboss.org/docs/DOC-13933}
*
* @param obj objeto a comparar con esta instancia.
* @return true si el objeto pasado es igual a este;
*
false en caso contrario
*/
@Override
public boolean equals(Object obj) {
// Si el objeto a comparar es nulo o no pertenece a la
// misma clase, la igualdad no se cumple
if (obj == null || obj.getClass() != getClass()) {
return false;
}
// si el objeto pasado es este objeto, la igualdad se cumple
if (obj == this) {
return true;
}
// comparación en base a la 'business key'
Cliente rhs = (Cliente) obj;
return new EqualsBuilder()
.append(this.nombre, rhs.nombre)
.append(this.apellido1, rhs.apellido1)
.append(this.apellido2, rhs.apellido2)
.append(this.fechaNacimiento, rhs.fechaNacimiento)
.isEquals();
}
/**
* Implementación de toString() pare este objeto de modelo.
* Se ha utilizado la clase StringBuilder como base de implementación.
*
* NOTA: Hay que tener mucho cuidado con volcar en este método
*
relaciones con otros objetos (EstadoCivil en este caso)
107 de 198
Framework Atlas
Normativa
*
porque una linea de log puede provocar la carga de muchos
*
objetos de base de datos, dependiendo del grado de
*
enlazamiento entre los objetos de dominio.
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Cliente [idCliente=").append(idCliente)
.append(", nombre=").append(nombre)
.append(", apellido1=").append(apellido1)
.append(", apellido2=").append(apellido2)
.append(", direccion=").append(direccion)
.append(", fechaNacimiento=").append(fechaNacimiento)
.append(", telefono=").append(telefono)
.append(", estadoCivil=").append(estadoCivil) // relación 1-1
.append("]");
return builder.toString();
}
PRACTICA
. BUENA
}
ADEqualsHashcode
La implementación de equals y hashcode se debe realizar utilizando EqualsBuilder y
HashCodeBuilder tal y como se puede ver en el ejemplo de la clase cliente.
Es recomendable que el índice de granularidad de las entidades persistentes sea el adecuado, intentando
representar de forma estricta las entidades de negocio.
6.4.3.1
Mapeo relacional
Las clases de dominio se mapearán mediante las correspondientes anotaciones de Hibernate. A
continuación se muestra una tabla con algunas de las anotaciones de Hibernate más utilizadas. Aunque
aquí solamente se muestran las más utilizadas se podrán utilizar todas las anotaciones proporcionadas por
Hibernate que cumplen con el estándar JPA.
@Table
Indica la tabla con la que se va a mapear
@Id
Indica que este campo es identificador de la tabla
@GeneratedValue
Indica que este campo va a ser generado automáticamente
@SequenceGenerator
Indica la secuencia a utilizar para este campo
108 de 198
Framework Atlas
Normativa
NORMA
@Column
Indica el campo con el que se va a mapear este atributo
ADMapeoTabla
Cada clase de dominio será mapeada a una tabla de la base de datos, esto se hará con la
anotación @Table.
Ejemplo de mapeo a tabla
@Entity
@Table(name = "EJPL_CLIENTES")
public class Cliente implements java.io.Serializable {
Nota
No hay que olvidarse de que cada clase de domino anotada se debe incluir en el fichero de configuración
applicationContext-database.xml.
ADIdentificador
Todas las entidades persistentes deberán tener un atributo a modo de identificador único que
permita distinguir un objeto de otro de forma unívoca. Este atributo será de tipo Integer y estará
obligatoriamente generado por una secuencia.
NORMA
En el caso de que el modelo de datos ya exista en producción y no sea posible cumplir esta
norma se utilizará la anotación @AtlasLegacy en la clase de dominio.
Este atributo se anotará con la anotación @Id.
Al margen de este atributo se podrán crear otros identificadores únicos propios de la gestión
funcional de la tabla que no serán anotados con @Id.
Sólo existe una excepción en la cuál una primary key deberá estar compuesta por más de un
campo, y es en aquellas tablas que sirven para representar relaciones muchos a muchos
NORMA
entre otras tablas.
ADUsoAtlasLegacy
Se requiere una autorización excepcional por parte de ICM para el uso de la anotación
@AtlasLegacy en las clases de dominio de las entidades de modelos de datos heredados.
109 de 198
Framework Atlas
Normativa
Ejemplo de campo Id
@Id
@GeneratedValue(strategy = GenerationType.AUTO,
generator = "EJPL_SECUENCIA_ID_CLIENTE")
@SequenceGenerator(name = "EJPL_SECUENCIA_ID_CLIENTE",
sequenceName = "EJPL_SECUENCIA_ID_CLIENTE")
@Column(name = "ID_CLIENTE", unique = true,
nullable = false, precision = 9, scale = 0)
public Integer getIdCliente() {
return this.idCliente;
}
NORMA
ADRelaciones
No se permite el uso de relaciones muchos-a-muchos. Se deberán sustituir, siempre que sea
posible, por relaciones uno-a-muchos y/o muchos-a-uno.
En caso de no poder hacer dicha sustitución, se deberá consultar a ICM el uso de la posible
NORMA
relación muchos-a-muchos.
6.4.3.2
ADDinamicos
No se permite el uso de modelos dinámicos de Hibernate como sustitutivo de las entidades
POJOs de persistencia.
Tipos de datos BLOB y CLOB (LOB)
Los tipos de datos BLOB y CLOB hacen referencia a aquellos elementos utilizados en una bases de datos
para almacenar entidades de gran tamaño que puedan cambiar de forma dinámica, estando los primeros
enfocados a datos binarios (por ejemplo una imagen) y los segundos a datos de tipo carácter (por ejemplo
NORMA
un párrafo de texto con un tamaño considerable).
ADLobAnot
Los atributos de tipo Lob se anotarán con la anotación @Lob y se le indicará que se traiga bajo
demanda con la anotación @Basic(fetch=FetchType.LAZY)
110 de 198
Framework Atlas
Normativa
Ejemplo de definición de campo LOB
/**
*
* @return Devuelve el contenido del ficherote un campo LOB
*/
@Lob
@Column(name = "CONTENIDO")
@Basic(fetch=FetchType.LAZY)
public Blob getContenido() {
return contenido;
}
111 de 198
Framework Atlas
Normativa
6.4.4
Data Access Objects
En una arquitectura Java Enterprise Edition (JEE) es fundamental contar con un elemento propio de
acceso a datos que permita a las aplicaciones obtener y manipular los datos de la organización de una
manera estandarizada y óptima que ofrezca a los desarrolladores una interfaz sencilla y homogénea que
facilite los desarrollos aumentando la productividad y mejorando los tiempos de mantenimiento, a la vez
que ofrezca unas elevadas prestaciones de rendimiento en tiempo de ejecución.
El patrón DAO es uno de los patrones de diseño estándar de JEE. DAO permite encapsular el acceso y
manipulación de datos en una capa separada. Esta capa gestiona la conexión con la fuente de datos
(bases de datos relacionales, ficheros planos, sistema de ficheros remotos, etc.) para obtener y almacenar
dichos datos, ya que implementa el mecanismo de acceso necesario. Independientemente del tipo de
fuente de datos empleada, la capa DAO siempre proporciona un API uniforme a sus clientes, ocultando los
detalles de implementación.
La capa DAO se implementa sin estado. No almacena en caché resultados de ninguna consulta, ni datos
que el cliente pueda necesitar posteriormente. Esto provoca que los objetos DAO sean simples y evita
problemas potenciales de concurrencia
Diagrama de clases (extraído de “Core J2EE Patterns, Best Practices and Design Strategies” por Deepak
Alur, John Crupi y Dan Malks):
Spring proporciona un mecanismo adicional que permite integrar herramientas ORM en objetos DAO de
una forma mucho más sencilla, haciendo uso del componente Spring DAO.
Los DAOs pueden ser configurados a través de la inyección de dependencias así como participar de los
recursos y la gestión automática de transacciones que aporta Spring. La norma habitual en los desarrollos
será hacer uso de Hibernate Spring DAO, proporcionando funcionalidades adicionales que harán más
sencillo el uso de Hibernate.
Las ventajas obtenidas al hacer uso de Spring DAO con Hibernate:
·
Fácil de testear: La aproximación de inyección de dependencias aportada por Spring hace sencillo
cambiar implementaciones y configurar la localización de instancias del objeto SessionFactory de
112 de 198
Framework Atlas
Normativa
Hibernate, recursos JDBC, gestores de transacciones, etc. Esto hace sencillo aislar y testear cada
pieza relacionada con la persistencia de forma independiente.
·
Acceso común a excepciones: Spring puede mapear las excepciones producidas por la Hibernate,
convirtiéndolas de propietarias a una jerarquía común de manejo de excepciones
DataAccessException, permitiendo manejar excepciones no recuperables solo en las capas
apropiadas.
·
Gestión general de recursos: Spring maneja de forma automática la localización y configuración de
instancias SessionFactory, Datasources, etc., por lo que Spring ofrece una manera sencilla y
segura de poder acceder a los recursos. Por ejemplo, generalmente Hibernate necesita utilizar la
misma sesión para hacer un manejo eficiente de las transacciones, Spring de forma transparente
crea y enlaza sesiones al actual hilo de ejecución, etc.
ADHibernateDAOImpl
En cada bloque funcional de una aplicación se han de crear los DAOs que darán cobertura a los
accesos a la base de datos.
NORMA
Para crear un DAO se crearán dos clases, con la siguiente nomenclatura:
o
<nombre>DAO (Interfaz del DAO)
o
<nombre>DAOImpl (Implementación del DAO)
Donde <nombre> debe ser sustituido por el nombre del DAO.
Estas clases se incluirán en el paquete dao del bloque funcional correspondiente.
Las clases de implementación deben heredar de la clase HibernateDaoSupport, de esta forma
NORMA
se utiliza el modelo de DAO’s proporcionado por Spring.
ADDAOAnotacion
Las clases de implementación de DAO tienen que tener la anotación @Repository. (No incluir la
anotación en las interfaces)
113 de 198
Framework Atlas
Normativa
ADDAONomenclatura
Cuando los DAOs tengan operaciones de modificacion o alteración de datos seguirán la siguiente
nomenclatura:
o
Inserción: insertXXX, donde XXX será un nombre autodescriptivo, generalmente el
NORMA
nombre del objeto de domino.
o
Actualización: updateXXX, donde XXX será un nombre autodescriptivo, generalmente el
nombre del objeto de domino.
o
Eliminación: deleteXXX, donde XXX será un nombre autodescriptivo, generalmente el
nombre del objeto de domino.
o
Consultas: findXXX, donde XXX será un nombre autodescriptivo sobre la consulta a
realizar.
El nombre descriptivo XXX siempre será opcional.
NORMA
ADDAOHibernateTemplate
Todas las operaciones sobre la base de datos como insert, delete, select (equivalente a find en
Hibernate), etc…se deben realizar a través de la clase HibernateTemplate proporcionada por
Spring, evitando el uso directo de la sesión de Hibernate.
Ejemplo de uso de HibernateTemplate
/**
* {@inheritDoc}
*
* @param cliente El cliente
* @see ejpl.gestion.dao.ClienteDAO#insertCliente(ejpl.gestion.domain
* .Cliente)
*/
@Transactional(readOnly = false)
public void insertCliente(Cliente cliente) {
this.getHibernateTemplate().save(cliente);
}
Para facilitar la tarea de implementación de las operaciones CRUD en los DAOs, se proporciona dentro del
arquetipo una interfaz llamada BaseDAO y su correspondiente implementación, con los métodos básicos
ya implementados de tal forma que podemos crear nuestros DAOs heredando de esta clase DAO e
implementando solo aquellos métodos que sean específicos de nuestro DAO.
A continuación se muestra la interfaz BaseDAO:
114 de 198
Framework Atlas
Normativa
package ejpl.dao;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
/**
* DAO genérico con funcionalidad CRUD
*
* <p>Extiende esta interfaz si se requiere DAOs para los objetos de modelo sin
* necesidad de realizar cast de conversión de datos.
*
* @param <T> el tipo de objeto que manejará este DAO.
* @param <PK> la clave primaria del objeto de dominio.
*/
public interface BaseDAO <T, PK extends Serializable> {
/**
* Método genérico usado para obtener todos los objetos de un tipo
* particular. Este método es equivalente a obtener todas las filas
* de una tabla.
*
* <p>El número total de elementos que correspondería al método
* countAll() se puede obtener a través del método size() del objeto
* de lista devuelto.</p>
*
* @return Lista de los objetos recuperados de BD
*/
List<T> findAll();
/**
* Método genérico usado para obtener el total de objetos de un tipo
* particular.
* @return número de elementos totales en la tabla.
*/
Long countAll();
/**
* Obtiene todos los registros sin duplicados.
* <p>Si se utiliza este método, es imperativo que las clases de
* modelo implementen correctamente los métodos hashcode/equals.</p>
*
* <p>El número total de elementos que correspondería al método
* countAllDistinct() se puede obtener a través del método size() del
* objeto de lista devuelto.</p>
*
* @return Lista de los objetos recuperados de BD
*/
List<T> findAllDistinct();
/**
* Obtiene en número total de registros sin duplicados.
* @return número de elementos totales sin duplicados.
*/
Long countAllDistinct();
/**
* Método genérico para obtener un objeto basado en el tipo de clase
* y su identificador único. Si no se encuentra el objeto, este método
* devolverá null.
*
* @param id el identificador (clave primaria) del registro a obtener
* @return el objeto de base de datos recuperado
*/
T find(PK id);
/**
* Método para obtener una serie de elementos del sistema dados unos ordenes y filtros
* @param index Indice de paginacion actual.
115 de 198
Framework Atlas
Normativa
* @param pageSize Tamaño de pagina.
* @param orders Criterios de ordenacion
* @param filters Filtros de busqueda.
* @return <code>java.util.List</code> La lista de objetos encontrados
*/
List<T> find(int index, int pageSize, Order[] orders, Criterion[] filters);
/**
* Método para obtener el numero de elementos dada una serie de filtros
* @param filters Filtro de busqueda.
* @return <code>int</code> con el numero total de objetos encontrados.
*/
int count(Criterion[] filters);
/**
* Comprueba la existencia de un objeto en base a su clave primaria.
*
* @param id el identificador de la entidad
* @return - true si el objeto existe, false en caso contrario
*/
boolean exists(PK id);
/**
* Método genérico para grabar un objeto (maneja objetos nuevos y modificados).
* Si el objeto es nuevo, este se devolverá con la clave primaria generada para
* su inserción en base de datos.
*
* @param object el objeto a guardar
* @return el objeto persistente
*/
T insert(T object);
/**
* Método genérico para grabar un objeto (maneja objetos nuevos y modificados).
* Si el objeto es nuevo, este se devolverá con la clave primaria generada para
* su inserción en base de datos.
*
* @param object el objeto a guardar
*/
void insertOrUpdate(T object);
/**
* Método genérico para grabar actualizar un objeto
*
* @param object el objeto a guardar
*/
void update(T object);
/**
* Método genérico para eliminar un objeto de la base de datos en base a su
* clave primaria.
*
* @param id el identificador (clave primaria) del registro a obtener
*/
void delete(PK id);
/**
* Método genérico para eliminar un objeto de la base de datos
*
* @param object el objeto a eliminar
*/
void delete(T object);
/**
* Encuentra una lista de registos usando una 'named query'.
*
* @param queryName nombre de la consulta a ejecutar
* @param queryParams un objeto Map con los nombres de los parámetos y sus valores
* @return una lista con los registros encontrados
*/
List<T> findByNamedQuery(String queryName, Map<String, Object> queryParams);
}
La implementación de esta clase se puede ver en el paquete dao en la clase BaseDAOImpl.
116 de 198
Framework Atlas
Normativa
PRACTICA
BUENA
ADBaseDAO
En el caso de que en el proyecto se identifiquen otros métodos comunes a todos los DAOs
estos métodos se incorporaran en la interfaz BaseDAO y en su correspondiente
implementación.
La creación de nuevos DAOS se realizará utilizando los mecanismos de herencia sobre la clase BaseDAO.
Dentro de los arquetipos se ha incluido un ejemplo de nuevo DAO que accede a la tabla de clientes:
ClienteDAO.
El siguiente diagrama muestra el diagrama de clases con las dependencias de la implementación de este
nuevo DAO.
class dao
«interface»
BaseDAO
+
+
+
+
+
+
+
+
+
+
countAll() : Integer
countAllDistinct() : Integer
delete(PK) : void
exists(PK) : boolean
findAll() : List<T>
findAllDistinct() : List<T>
findByNamedQuery(String, Map<String, Object>) : List<T>
get(PK) : T
insert(T) : T
saveOrUpdate(T) : void
T
PK:extends Serializable
HibernateDaoSupport
BaseDAOImpl
«interface»
ClienteDAO
+
+
findClientes(int, int, Object, Object) : List<Cliente>
findClientesTotal(Object) : int
-
log: Log = LogFactory.getL... {readOnly}
persistentClass: Class<T>
+
+
+
+
+
+
+
+
+
+
#
+
+
BaseDAOImpl(Class<T>)
BaseDAOImpl(Class<T>, SessionFactory)
countAll() : Integer
countAllDistinct() : Integer
delete(PK) : void
exists(PK) : boolean
findAll() : List<T>
findAllDistinct() : List<T>
findByNamedQuery(String, Map<String, Object>) : List<T>
get(PK) : T
getLog() : Log
insert(T) : T
saveOrUpdate(T) : void
ClienteDAOImpl
+
+
+
ClienteDAOImpl()
findClientes(int, int, Object, Object) : List<Cliente>
findClientesInternal(int, int, Object, Object, String) : Query
findClientesTotal(Object) : int
117 de 198
Framework Atlas
Normativa
A continuación se muestra un posible código de ejemplo para las clases ClienteDAO y ClienteDAOImpl,
que heredan de BaseDAO y añaden dos métodos que no existen en la clase padre.
Ejemplo: ClienteDAO
package ejpl2.dao;
import java.util.List;
import ejpl2.domain.Cliente;
/**
* <p>Clase que extiende el CRUD básico proporcionado por Atlas. Esta clase es
* una demostración de como usar BaseDAO y completar con más métodos de
* acceso a BBDD.</p>
*
* <p>Si no hiciesen falta más métodos, no sería necesario crear ninguna
clase,
* simplemente definir ClienteDAO en el contexto de Spring como sigue:
*
* <pre>
*
<bean id="clienteDAO" class="ejpl2.dao.BaseDAOImpl">
*
<constructor-arg value="ejpl2.domain.Cliente"/>
*
</bean>
* </pre>
*
* </p>
*
* @author ICM
*
*/
public interface ClienteDAO extends BaseDAO<Cliente, Integer> {
/**
* Este metodo recupera todos los clientes del sistema.
*
* @param index Indice de paginacion actual.
* @param pageSize Tamaño de pagina.
* @param order Criterio de ordenacion.
* @param filter Filtro de busqueda.
*
* @return <code>java.util.List</code> objecto que representa la lista de
clientes.
*/
List<Cliente> findClientes(int index, int pageSize, Object order, Object
filter);
/**
* Este metodo obtiene el numero total de clientes del sistema.
*
* @param filter Filtro de busqueda.
*
* @return <code>int</code> con el numero total de cliente encontrados.
*/
int findClientesTotal(Object filter);
}
118 de 198
Framework Atlas
Normativa
Ejemplo: ClienteDAOImpl
package ejpl2.dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import
import
import
import
org.hibernate.Query;
org.springframework.stereotype.Repository;
org.springframework.transaction.annotation.Propagation;
org.springframework.transaction.annotation.Transactional;
import ejpl2.domain.Cliente;
/**
* Objeto DAO de tratamiento en base de datos de la clase Cliente.
*
* @author ICM
*/
@Repository
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class ClienteDAOImpl extends BaseDAOImpl<Cliente, Integer>
implements ClienteDAO {
/**
* Constructor por defecto. Pasa a BaseDAO el objeto Class de
* parametrización de la clase.
*/
public ClienteDAOImpl() {
super(Cliente.class);
}
/**
* {@inheritDoc}
*
* @see ejpl2.dao.ClienteDAO#findClientes(int, int, java.lang.Object,
* java.lang.Object)
*/
@SuppressWarnings("unchecked")
public List<Cliente> findClientes(int index, int pageSize, Object order,
Object filter) {
null);
Query query = findClientesInternal(index, pageSize, order, filter,
// Ejecuta la query
return query.setFirstResult(index).setMaxResults(pageSize).list();
}
/**
* {@inheritDoc}
*
* @see ejpl2.dao.ClienteDAO#findClientesTotal(java.lang.Object)
*/
public int findClientesTotal(Object filter) {
Query query = findClientesInternal(0, 0, null, filter, "Select
count(c)");
119 de 198
Framework Atlas
Normativa
// Ejecuta la query
return ((Long) query.uniqueResult()).intValue();
}
/**
* Método interno para buscar clientes
*
* @param index Indice de paginacion actual.
* @param pageSize Tamaño de pagina.
* @param order Criterio de ordenacion.
* @param filter Filtro de busqueda.
* @param select clausula select para retornar distintos valores
* @return objeto Query para entregar a Hibernate
*/
private Query findClientesInternal(int index, int pageSize, Object order,
Object filter,
String select) {
StringBuffer strQuery = new StringBuffer();
Map<String, String> params = new HashMap<String, String>();
if (select != null) {
strQuery.append(select);
}
strQuery.append(" from Cliente c");
// Concatena la clausula where al filtro si es necesario
String strFiltro = (filter == null) ? null : filter.toString();
if (strFiltro != null && !strFiltro.equals("")) {
strQuery.append(" where c.nombre like :filtro ");
params.put("filtro", "%" + strFiltro + "%");
}
// Concatena la clausula order al filtro si es necesario
String strOrder = (order == null) ? null : order.toString();
if (strOrder != null && !strOrder.equals("")) {
strQuery.append(" order by c.").append(strOrder);
}
// Selecciona el parámetro del filtro si es necesario
Query query = getSession().createQuery(strQuery.toString());
// Incluimos los parametros
for (String key : params.keySet()) {
query.setString(key, params.get(key));
}
// Devolver el objeto query
return query;
}
}
120 de 198
Framework Atlas
Normativa
Atención
Puede ocurrir que un DAO no necesite ningún método adicional a los del BaseDAO, en ese caso no es
necesario crear ninguna clase, simplemente definir un objeto en el contexto de Spring (applicationContextdao.xml) de la siguiente forma:
<bean id="miDAO" class="ejpl.dao.BaseDAOImpl">
<constructor-arg value="ejpl.domain.Cliente"/>
<constructor-arg ref=”sessionFactory”/>
</bean>
Nota
NORMA
NORMA
Los daos se deben inyectar en el contexto de Spring en el fichero applicationContext-dao.xml
ADCatalogos
No se permiten realizar actualizaciones en tablas de catálogos generales (SUCA, CATA, etc).
Tampoco se podrán realizar borrados en cascada sobre tablas de catálogos.
ADRemoto
El acceso a tablas remotas se debe hacer mediante sinónimos remotos y no por database link.
ADHQL
PRACTICA
BUENA
Se deberá utilizar en la medida de lo posible el lenguaje de acceso a datos HQL, por ser un
lenguaje más enfocado a objetos que el propio SQL.
Aún así se podrá extender este modelo haciendo uso del lenguaje SQL siempre y cuando sea
necesario.
Esto será necesario en casos de querer usar querys SQL no ANSI-Estándar, querys que por
su complejidad sea más adecuado SQL en lugar del mapeo objeto-relacional, operaciones de
larga duración del tipo batch, streaming de BLOBs, operaciones de tipo “select” complejas, etc.
121 de 198
Framework Atlas
NORMA
Normativa
ADSQL
En el caso de utilizar SQL se implementará mediante los mecanimos que proporciona Hibernate
para la ejecución de queries SQL nativas. (createSQLQuery)
Ejemplo de uso de SQL
public List getQueryData() {
SQLQuery query = getHibernateTemplate().getSession().createSQLQuery(sql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();
}
ADSQLUso
En el caso de utilizar SQL se deberan tener en cuenta las siguientes restricciones:
NORMA
·
No se podrán utilizar sentencias SQL-DDL desde el código ni utilizar los mecanismos de
Hibernate que permitan realizar ese tipo de operaciones desde el código.
·
No se deben utilizar las sentencias SELECT * en su lugar se incluirán los nombre de los
campos que en realidad se van a consultar.
·
En el caso de utilizar una sentencia SELECT FOR UPDATE se hará con la clausula NO
WAIT.
6.4.4.1
Ejecución de consultas
Es normal en todos los DAOs la ejecución de consultas en la base de datos.
Por motivos de optimización de las consultas es necesario que los parámetros utilizados como criterios no
se adjunten en el String de la consulta y sean pasados como ‘named parameters’.
A continuación se muestra un ejemplo incorrecto y otro correcto de creación de consultas:
Creación INCORRECTA de consultas
String strQuery = "from Cliente where nombre = '" + nombre + "'"; // MAL
Query query = getSession().createQuery(strQuery);
return query.list();
Creación CORRECTA de consultas
String strQuery = "from Cliente where nombre = :nombre"; // BIEN
Query query = getSession().createQuery(strQuery);
query.setString("nombre", nombre);
return query.list();
122 de 198
Framework Atlas
NORMA
Normativa
ADNamedParameter
El uso de criterios en las consultas de los DAOs ha de hacerse siempre a través de ‘named
parameters’.
123 de 198
Framework Atlas
Normativa
6.4.4.2
Manejo de excepciones
Un DAO deberá esforzarse en aislar el manejo de excepciones gracias a Spring, por lo que solo podrá
lanzar DataAccessException, de manera que el tratamiento de las excepciones que se pudiesen provocar
a este nivel seria gestionadas en capas superiores (capa de negocio).
Esto se justifica ya que por ejemplo carece de sentido lanzar java.lang.Exception, ya que es demasiado
genérica y no transmite ninguna información acerca de la raíz del problema. Tampoco tendrá sentido
NORMA
lanzar excepciones de tipo java.sql.SQLException, ya que es una excepción JDBC de bajo nivel.
6.4.4.3
DAOExcepciones
Todos los métodos de los DAOs sólo podrán lanzar excepciones de tipo DataAccessException.
Transaccionalidad
El uso del modelo de anotaciones que propone Spring permite gestionar de forma automática y sencilla la
semántica transaccional, esto se pronuncia en un código portable con respecto al gestor transaccional
utilizado, por ejemplo se podría alterar el uso del gestor transaccional de Hibernate por el de otro sistema
de persistencia que soporte el estándar JTA.
ADTransaccion
La gestión de las transacciones se hará mediante anotaciones.
Los DAOs tendrán por defecto todos los métodos como de lectura y propagación supports, esto se
definirá con una anotación @Transaction a nivel de clase. (@Transactional(readOnly =
NORMA
true, propagation = Propagation.SUPPORTS)
Los método de los DAOs que alteren datos (insert, update, delete) modificarán el
comportamiento por defecto, mediante el atributo “readOnly=false”.
(@Transactional(readOnly = false))
De forma excepcional, se permite modificar el comportamiento por defecto de un método con
respecto al atributo propagación “Propagation.SUPPORTS” por uno de tipo
“Propagation.REQUIRES_NEW”.
El uso de cualquier atributo de propagación que no sea “Propagation.SUPPORTS “ o
“Propagation.REQUIRES_NEW” deberá de justificarse y consesuarse con ICM.
En el ejemplo de implementación de un DAO que podemos ver mas arriba podemos observar el uso de las
anotaciones tal y como se indica en la norma.
124 de 198
Framework Atlas
Normativa
Aunque se comentó en la sección de servicios, recalcar que serán las capas superiores (servicios) la
encargadas de gestionar el contexto transaccional y no la capa de acceso a datos, por lo que los DAOs se
limitarán a ejecutar un método en un contexto transaccional (si al invocar dicho método el contexto ya está
creado), o a ejecutar el método sin transacción (en caso de invocar al DAO sin un contexto transaccional).
Esto se cumplirá en la mayoría de los casos, ya que al permitir (eventualmente)
Propagation.REQUIRES_NEW, se permite que el propio DAO cree un contexto transaccional solo para la
ejecución de un método concreto.
ADRollback
NORMA
Un DAO no puede gestionar rollback de transacción, es decir, se prohíbe el uso de
o
“rollbackFor = xxxException.class”,
o
“rollbackForClassName = {"xxxException"}”,
o
“noRollbackFor = xxxException.class” ,
o
“noRollbackForClassName = {"xxxException"}”.
Cuando los DAOs generen un error de tipo “DataAccessException” o “RuntimeException” se
traducirá en un rollback automático.
Según se comenta en el apartado de servicios de negocio, los atributos “rollbackFor”,
“rollbackForClassName”,”noRollbackFor” y “noRollbackForClassName” solo tendrán sentido en la
capa de servicios con objeto de poder realizar rollback para las excepciones de negocio.
125 de 198
Framework Atlas
Normativa
6.4.5
Llamada a Procedimientos Almacenados
La llamada a procedimientos almacenados de Oracle desde Hibernate se puede de dos formas distintas,
dependiendo de si el procedimiento devuelve un cursor y si tiene parámetros de salida o no:
ADStoredProc
NORMA
La llamada a procedimientos almacenados de Oracle se realizará de la siguiente forma:
1)
Si el procedimiento almacenado devuelve un cursor y no tiene parámetros de salida:
Mediante Hibernate utilizando Named Queries
2)
Si el procedimiento almacenado no devuelve un cursor o tiene parámetros de salida:
Se hará mediante un CallableStatement
En los siguientes sub-apartados se muestra la forma de invocarlos en cada uno de estos dos casos.
6.4.5.1
Llamada a procedimientos almacenados mediante Hibernate utilizando Named Queries
A continuación se muestra un ejemplo de procedimiento almacenado que devuelve un cliente (el ejemplo
puede implementarse en un arquetipo recien creado).
1) Creación de procedimiento almacenado:
Ejemplo de procedimiento almacenado
create or replace procedure EJPL_PROC_BUSCAR_POR_ID
(
z_resultado out SYS_REFCURSOR,
w_id IN integer) is
begin
OPEN z_resultado FOR
SELECT ID_CLIENTE,NOMBRE,APELLIDO1,APELLIDO2,
DIRECCION,TELEFONO,FC_NACIMIENTO,FK_ESTADO_CIVIL
FROM EJPL_CLIENTES WHERE ID_CLIENTE = w_id;
end EJPL_PROC_BUSCAR_POR_ID;
2) Modificación de la entidad de dominio para incluir la named query (Cliente.java):
Ejemplo de entidad que define la Named Query
@Entity
@org.hibernate.annotations.NamedNativeQuery(name = "buscarClientePorId", query
= "call EJPL_PROC_BUSCAR_POR_ID(?,:w_id)", callable = true, resultClass =
Cliente.class)
@Table(name = "EJPL_CLIENTES")
public class Cliente implements java.io.Serializable {
…
}
126 de 198
Framework Atlas
Normativa
3) Modificación del DAO de Clientes para obtener un cliente por su identificador utilizando el procedimiento
almacenado creado (ClienteDAOImpl):
Ejemplo de DAO que utiliza la Named Query
…
public Cliente findById(final Integer idCliente) {
// Implementación de ejemplo utilizando procedimiento almacenado
List<Cliente> clientes = (List<Cliente>)
getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(final Session session) throws
HibernateException, SQLException {
return session.getNamedQuery("buscarClientePorId") //
.setParameter("w_id", idCliente) //
.list();
}
});
if(clientes != null && clientes.size() > 0) {
return clientes.get(0);
}
return null;
// Implementación sin utilizar procedimiento almacenado
// return (Cliente) getHibernateTemplate().get(
//
"xxxx.bloquefuncionaln.domain.Cliente", idCliente);
}
…
6.4.5.2
Llamada a procedimientos almacenados mediante CallableStatement
A continuación se muestra un ejemplo de invocación a un procedimiento almacenado que no devuelve un
cursor, y/o que tiene parámetros de salida:
1) Creación de procedimiento almacenado:
Procedimiento almacenado sis_proc_ident_cod
create or replace procedure SIS_PROC_IDENT_COD
(
wcodigo in out varchar2,
wtexto out varchar2) is
begin
…
end EJPL_PROC_BUSCAR_POR_ID;
2) Modificación del DAO de Clientes para obtener un cliente por su identificador utilizando el procedimiento
almacenado creado (ClienteDAOImpl):
EjemploDAO.java
127 de 198
Framework Atlas
Normativa
public String validaDocumento(String documento) throws DataAccessException {
Connection con = getSessionFactory().getCurrentSession(). connection();
CallableStatement cst = null;
String resultadoCodigo = null;
try {
cst = con.prepareCall("{call sis_proc_ident_cod(?, ?)}");
cst.setString(1, documento.toUpperCase());
cst.registerOutParameter(1, java.sql.Types.VARCHAR);
cst.registerOutParameter(2, java.sql.Types.VARCHAR);
// Llamada al procedimiento almacenado
cst.execute();
resultadoCodigo = cst.getString(1);
} catch (SQLException e) {
throw new DataAccessException("Error validando documento", e);
}
finally {
cst.close();
}
return resultadoCodigo;
}
128 de 198
Framework Atlas
Normativa
6.4.6
Cachés en Hibernate
El uso adecuado de mecanismos de caché permitirá aumentar el rendimiento de aplicaciones que accedan
a entornos persistentes de información al almacenar las estructuras de objetos en memoria, evitando
volver a buscar dichos objetos en bases de datos, ahorrando multitud de accesos y por consiguiente
grandes cantidades de tiempo.
Los pasos comunes que se siguen en el acceso a datos mediante caches podrían resumirse como:
· Se realiza una consulta de acceso a datos.
· Se comprueba si los objetos requeridos se encuentran en caché. Si los objetos están en caché se
devuelven directamente.
· Si los objetos no se encuentran en caché, se recuperan desde un almacén de datos persistente y se
almacenan en caché para un uso futuro.
6.4.6.1
Las cachés de primer y segundo nivel
Hibernate cuenta con dos tipos de cachés, la denominada caché de primer nivel y la de segundo nivel:
Figura 1 : Caché de primer y segundo nivel en Hibernate
La cache de primer nivel se corresponde al objeto sesión que se obtiene de la factoría de sesiones de
Hibernate. Esta caché de primer nivel se encargará de almacenar los objetos que se recuperan de la base
de datos. Otra ventaja obtenida en paralelo es que el objeto sesión actúa como fachada y situaciones
como accesos, lazos circulares, etc. solo afecta a la propia sesión sin causar efectos colaterales al resto de
sesiones abiertas.
129 de 198
Framework Atlas
Normativa
Una norma fundamental cuando se utilizan cachés, es almacenar sólo lo que estamos seguros que se
reutilizará. En otro caso, lo mejor es no utilizar la caché. Cuando se trabaje con una sesión y se mantenga
activa en memoria, se debe tener en cuenta que es una caché de primer nivel, y se debe eliminar todo
aquello que carezca de sentido su almacenaje en la misma.
Se recomienda que cuando se desee eliminar objetos de la caché se invoque al método evict() para que se
elimine de caché el objeto pasado como parámetro. Existe también un método clear() que permite eliminar
todos los objetos que se encuentren en ese momento en la caché, limpiándola así por completo. Ambos
métodos, son útiles para políticas de sincronización entre cachés.
La caché de segundo nivel se acoplará a la sesión de Hibernate absorbiendo todos los fallos que se
produzcan en ésta. La gran ventaja de utilizar una caché de segundo nivel es que desaparecen los
problemas de actualizaciones concurrentes entre sesiones. La caché de segundo nivel se sitúa al mismo
nivel que el objeto SessionFactory de Hibernate, recogiendo y coordinando los objetos con los que trabajan
las diferentes sesiones.
El problema de las actualizaciones concurrentes supone un grave quebradero de cabeza para cualquier
sistema de caché. Sea cual sea el modelo que se desee utilizar siempre se tendrá algún problema en
relación con las actualizaciones concurrentes, ya sea en mayor o menor medida. La gran ventaja de una
caché de segundo nivel, es que ayuda a mitigar estos problemas, al tiempo que alivia de la responsabilidad
de almacenar datos temporales, a la caché de primer nivel.
La recomendación general con una caché de segundo nivel es utilizar una aproximación de sesión por
transacción de aplicación (Sesión por vista). Con una caché de segundo nivel, el gran problema de no
aprovechamiento de la caché de primer nivel del que adolecen algunos modelos, desaparece parcialmente.
Si un objeto no se encuentra en la caché de primer nivel, Hibernate tratará de obtenerlo de la caché de
segundo nivel, de modo que en caso de encontrarse ahí se consigue el ahorro de un hit en la base de
datos. Cerrar las sesiones pues, ya no es un problema tan grave (a nivel de rendimiento), ya que aunque
se tengan que realizar cientos y cientos de consultas recurrentes, los datos estarán en la caché de
segundo nivel, y la pérdida de rendimiento ya no será tan grande.
Hibernate permite habilitar individualmente la caché para cada una las entidades. De este modo, se podrá
indicar que clases se beneficiarán del uso de una caché, ya que como según lo comentado anteriormente,
puede que no todas las clases del sistema se beneficien. Además de esto, al habilitar la caché es
necesario establecer la estrategia de concurrencia que Hibernate utilizará para sincronizar la caché de
primer nivel con la caché de segundo nivel, y ésta última con la base de datos. Hay cuatro estrategias de
concurrencia predefinidas.
A continuación aparecen listadas por orden en base a restricciones expresadas en términos de aislamiento
transaccional:
130 de 198
Framework Atlas
Normativa
Transactional: Garantiza un nivel de aislamiento hasta repeatable read, si se necesita. Es el nivel más
estricto. Se recomienda su uso cuando no se pueda permitir datos que queden desfasados. Esta
estrategia sólo se puede utilizar en entornos basados en clusters, es decir, con cachés distribuidas.
Read-write: Mantiene un aislamiento hasta el nivel de commited, utilizando un sistema de marcas de
tiempo (timestamps). El caso de uso recomendable es el mismo que para la estrategia transactional pero
con la diferencia de que esta estrategia no se puede utilizar en entornos basados en clusters.
Nonstrict read-write: No ofrece ninguna garantía de consistencia entre la caché y la base de datos.
Para sincronizar los objetos de la caché con la base de datos se utilizan timeouts, de modo que cuando
caduca el timeout se recargan los datos. Con esta estrategia se tiene un intervalo en el cual existe el
riesgo de obtener objetos desfasados. Cuando Hibernate realiza una operación de flush() en una sesión,
se invalidan los objetos de la caché de segundo nivel. Aún así, esta es una operación asíncrona y nunca
se tienen garantías de que otro usuario no pueda leer datos erróneos. A pesar de todo esto, esta
estrategia es ideal para almacenar datos que no sean demasiado críticos.
Read-only: Es la estrategia de concurrencia menos estricta. Ideal para datos que nunca cambian.
NORMA
ADCache2nivel
No se permite el uso de cachés de segundo nivel en Hibernate.
En el caso de que se justifique su uso se solicitará una autorización excepcional a ICM.
6.4.6.2
Las cachés distribuidas
Las aplicaciones con decenas de miles de usuarios probablemente necesiten ejecutarse en un entorno
distribuido, es decir, en cluster. Llegado este momento, el único elemento de Hibernate que necesitaría
configurarse es la caché de segundo nivel.
Hay dos modos de configurar una caché de segundo nivel de Hibernate en un cluster:
· El más sencillo, sin ninguna duda, es colocar en cada nodo del cluster una instancia del proveedor
de caché, por ejemplo EHCache, y confiar en los timeout para la sincronización de los proveedores
de caché de los diferentes nodos. Este sistema es muy simple, y no presenta retardos de
sincronización entre los nodos, ya que no existe sincronización alguna.
· El segundo modo, es instalar un proveedor de caché más avanzado que soporte la sincronización
de las cachés de los diferentes nodos. El proveedor recomendado por Hibernate para esta tarea es
JBossCache, un proveedor totalmente transaccional basado en la librería de multicasting, JGroups,
si bien no deja de ser una recomendación por lo que llegado el caso podrá optarse por otro
proveedor certificado en Hibernate.
131 de 198
Framework Atlas
Normativa
DAOCacheDistribuida
En concordancia con el apartado anterior, se debe justificar el uso de cachés distribuidas en
NORMA
entornos basados en cluster, especificando que ventajas aporta con respecto a otro tipo de
soluciones que nos proporcione el entorno ya sea a nivel de bases de datos, servidores de
aplicaciones, etc.
Además el volumen de información a manejar crecerá sustancialmente (replicación) por lo que se
tendrá que justificar su uso en contraposición con otros requisitos no funcionales (como alta
disponibilidad), ausentes en el entorno de desarrollo/preproducción.
6.4.6.3
La caché de consultas
La caché de consultas de Hibernate permite almacenar las consultas realizadas recientemente, de modo
que si se vuelven a realizar posteriormente, se recuperen los resultados de un modo mucho más ágil (sin
PRACTICA
BUENA
volver a ejecutar la select a base de datos).
ADRendimiento
Se desaconseja el uso de la caché de consultas de hibernate, excepto en aplicaciones que sólo
realicen consultas (no realicen operación de inserción/borrado/actualización), y realmente
hagan uso intensivo de esta caché.
132 de 198
Framework Atlas
Normativa
7
CONFIGURACION
En todas las aplicaciones es necesario establecer ciertos parámetros que permitan modificar el estado o la
configuración del sistema. Así, por ejemplo, a la hora de desarrollar una aplicación se suelen definir
constantes y valores predeterminados que quizás interese cambiar a lo largo del tiempo, por lo que
incluirlos en el código sería un grave error ya que cada modificación implicaría una recompilación del
código.
Dentro de la configuración de una aplicación vamos a distinguir distintos tipos de configuraciones:
o
Configuración particular de la aplicación
o
Configuración de componentes comunes del framework
Además dentro de estas configuraciones nos podemos encontrar con configuración que depende del
entorno en el que se ejecute la aplicación (local, desarrollo, validación y producción) y la que no depende
de dicho entorno.
Las variables de configuración de una aplicación pueden estar situadas en distinto lugar, en función de la
naturaleza de la variable:
·
Librería de configuración común por entorno: Toda la configuración de componentes
comunes del framework que es dependiente del entorno y no se necesita personalizar en las
aplicaciones (por tanto sólo depende del entorno y no de la aplicación) se ubica en la librería atlascomunes-configuracion-lib. En los entornos de ICM (desarrollo, validación y producción) esta
librería ya se encuentra configurada para dicho entorno y publicada en el servidor de aplicaciones
para que todas las aplicaciones puedan acceder a ella, de manera que el proveedor no necesita
realizar ninguna acción con esta librería.
o
Un ejemplo de configuración de este tipo podría ser las políticas de seguridad aplicadas en
cada entorno, o la configuración del servidor de planificación ControlM.
·
Fichero application.properties: Este fichero de configuración se encuentra incluido en el
directorio src/main/resources/conf de las aplicaciones. En él se deben incluir todas las variables de
configuración de la aplicación que NO dependan del entorno en el que esté desplegada (no
dependen de que la aplicación se desplegue en local, desarrollo, validación o producción).
o
Un ejemplo de variable de configuración de este tipo es la que indica el nombre del fichero
de menús de la aplicación (menu.xml).
Si se trata de variables de configuración referentes a queries (tanto las queries del componente de
lista de valores, como queries para la integración con documentum), estas variables se incluirán en
el fichero queries.properties.
·
Fichero environment.properties: Este fichero de configuración se encuentra incluido en el
directorio src/main/resources de las aplicaciones. En él se deben incluir todas las variables de
133 de 198
Framework Atlas
Normativa
configuración de la aplicación SI no dependan del entorno en el que esté desplegada (dependen
de que la aplicación se desplegue en local, desarrollo, validación o producción). Durante el
despliegue de una aplicación en los entornos de ICM, este fichero será sustituido por su homólogo
correspondiente al entorno en el que se desea desplegar.
o
Un ejemplo de variable de configuración de este tipo es la que indica la ubicación física del
fichero de log de la aplicación.
CONFEntorno
NORMA
El fichero enviroment.properties deberá incluir todas las variables que son dependientes del
entorno y que se definan a nivel de aplicación. Este es el único fichero que se actualizará a sus
valores correspondientes en el despliegue del aplicativo a los distintos entornos. (local, desarrollo,
validación, producción, etc). Por lo tanto cada vez que se incluya una variable en el fichero
enviroment.properties de la carpeta src/main/resources se debe incluir dicha variable en todos los
ficheros enviromnet.properties de todos los entornos.
CONFParticular
El fichero application.properties deberá incluir las variables que se definan a nivel de aplicación
y que no dependan el entorno en el que está desplegada (local, desarrollo, validación,
producción, etc.). También deberá incluir aquellas variables de componentes o servicios del
NORMA
framework que se necesite personalizar para la aplicación y que no dependan del entorno.
Si se trata de variables de configuración referentes a queries (tanto las queries SQL/HQL del
componente de lista de valores, como queries para la integración con documentum en DQL),
estas variables se incluirán en el fichero queries.properties. Las variables de este fichero
deberán empezar por “queryCode.” y estarán agrupadas dentro del fichero de manera que se
facilite su lectura.
Los módulos de tipo librería en lugar de esta norma les aplica la norma CONFLIB.
Los módulos de tipo librería han de definir su configuración de forma distinta para que puedan convivir
varias librerías y sus configuraciones dentro de un proyecto. Por ello han de seguirse las siguientes
instrucciones:
·
Fichero application-yyyy.properties: En el caso de que una librería incluya variables de
configuración cuyos valores son los mismos para todos los proyectos que usen estas librerías y
estos valores no dependan del entorno se creará un fichero llamado application-yyyy.properties
134 de 198
Framework Atlas
Normativa
,donde yyyy es el nombre de la librería, Este fichero se situará en el directorio
src/main/resources/conf de la librería para que se incluya dentro del jar de la misma.
Si se trata de variables de configuración referentes a queries, estas variables se incluirán en el
fichero queries-yyyy.properties donde yyyy es el nombre de la librería. El fichero irá situado en el
mismo directorio que el anterior.
Las aplicaciones que utilicen la librería deberán referenciar estos ficheros de configuración dentro
del fichero de contexto de Spring applicationContext-general.xml en el bean propertyConfigurer.
·
Fichero environment.properties: Las librerías NO pueden incluir este fichero de configuración ya
que sino sería necesario generar distintas versiones de la librería una por cada entorno. Cuando
una librería requiera de variables de configuración que dependen del entorno estas se incluirán en
el fichero de configuración de la aplicación que use esta librería (nunca dentro de la librería). Es
muy importante que las variables sigan la nomenclatura adecuada para reconocer dentro de una
aplicación a quién pertenecen esas variables de configuración.
CONFParticularLIB
En los módulos de tipo librería el fichero de configuración se llamará applicationyyyy.properties donde yyyy se corresponde con el nombre de la librería. Este fichero deberá
NORMA
incluir las variables que se definan a nivel de aplicación y que no dependan el entorno en el que
está desplegada (local, desarrollo, validación, producción, etc.). Este fichero irá incluido dentro
del jar de la librería.
Si se trata de variables de configuración referentes a queries estas variables se incluirán en el
fichero queries-yyyy.properties donde yyyy se correponde con el nombre de la librería. Las
variables de este fichero deberán empezar por “queryCode.” y estarán agrupadas dentro del
fichero de manera que se facilite su lectura.
NORMA
CONFEntornoLIB
Los módulos de tipo librería NO pueden incluir el fichero enviroment.properties en el directorio
src/main/resources. En el caso de que la librería necesite variables que son dependientes del
entorno, estas se incluirán en el fichero enviroment.properties de la aplicación que utilice la
librería.
135 de 198
Framework Atlas
Normativa
CONFNomenclatura
La nomenclatura de las variables propias de la aplicación será:
xxxx.nombre
NORMA
Donde xxxx es el nombre del módulo y nombre el nombre de la variable.
Estas variables deberán incluir un comentario con la descripción de las mismas. Los comentarios
deben aportar claridad, no abusar de ellos intentando que el propio fichero sea autodescriptivo.
Para ello ayudará la selección adecuada de los nombres de los parámetros.
Los parámetros que hacen referencia a una misma funcionalidad deben ser incluidas en un grupo
de elementos adecuadamente comentados. Cuando existan grupos funcionales deben indicarse
introduciendo un nivel de anidamiento más en esa estructura para agrupar claramente los valores
propios para cada instancia. Esta situación se puede presentar cuando por ejemplo se trabaje con
servidores de correo electrónico, donde los datos de conexión y cuentas pueden ser diferentes.
NORMA
CONFSEG
Los ficheros de configuración no contendrán información que supongan riesgo de seguridad
según lo establecido por la LOPD, como por ejemplo contraseñas no cifradas.
A continuación se muestra un ejemplo de cómo obtener el valor de una variable de configuración definida
en el fichero application.properites o environment.properties, desde un fichero de Spring:
Ejemplo de fichero application.properties ó environment.properties
politicas.url=http://localhost:9080/index.jsf
Ejemplo de cómo obtener el valor de una variable de configuración desde Spring
<bean id="miBean" class="paquete.MiClase">
<property name="url" value="${politicas.url}"/>
</bean>
Para obtener el valor de una variable de configuración desde Java, se recomienda inyectar el valor en la
clase Java a través de un bean de Spring (según se muestra en el ejemplo anterior).
Aunque menos recomendada para los casos habituales, existe otra forma alternativa que consiste en
cargar el fichero de propiedades del que se desea obtener la variable y obteniendo su valor de este, según
se muestra en el siguiente ejemplo:
136 de 198
Framework Atlas
Normativa
Ejemplo de cómo obtener el valor de una variable de configuración desde Java
import java.util.Properties;
import atlas.core.general.PropertiesLoader;
public class EjemploProperties {
/** singleton para cargar properties de fichero */
private static final Properties PROPS = PropertiesLoader.getInstance(
new String[] {"conf/application.properties"}).getProperties();
/** Variable obtenida del fichero application.properties */
public static final String POLITICAS_URL =
PROPS.getProperty("politicas.url");
/**
* Devuelve el valor de la URL
* @return El valor de la URL leída del fichero application.properties
*/
public String getURLPoliticas() {
return POLITICAS_URL;
}
}
137 de 198
Framework Atlas
Normativa
8
SERVICIOS BASICOS
El framework Atlas ofrece un conjunto de servicios básicos para cubrir aquellos requisitos comunes a la
mayoría de las aplicaciones.
Los arquetipos ya vienen preconfigurados para poder utilizar estos servicios básicos.
A continuación se muestran con más detalle cada uno de estos servicios básicos.
8.1
SERVICIO DE AUTENTICACION Y AUTORIZACION
La Comunidad de Madrid dispone de aplicaciones de carácter público y privado, dependiendo, tanto del
tipo de función que desempeñan como del tipo de usuarios al que van dirigidas. En el framework Atlas se
ha desarrollado el Servicio de Autenticación y Autorización para cubrir este requisito de gestión de
accesos.
Las aplicaciones de carácter privado limitaran su acceso a determinados usuarios. La forma de acceder a
este tipo de aplicaciones puede ser mediante dos mecanismos: certificado digital y/o login/password.
Los usuarios que tienen su acceso permitido a determinadas aplicaciones estarán dados de alta en alguno
de los repositorios que la Comunidad de Madrid dispone. En estos repositorios de usuarios se encuentra
toda la información de los usuarios y sus perfiles o roles de trabajo para cada aplicación. Estos repositorios
son los que se muestran a continuación:
Política
Repositorio a validar y acciones
LDAP
Almacena los datos de login de los usuarios de la intranet. Se utiliza para la
autenticación de los usuarios.
USU
Repositorio de usuarios y perfiles de la Comunidad de Madrid. Se utiliza
para la autorización de los usuarios.
USUI
Repositorio de usuarios y perfiles de la Comunidad de Madrid con acceso
desde Internet. Se utiliza para la autenticación y autorización de los
usuarios.
USUJ
Repositorio de usuarios y perfiles de la Comunidad de Madrid para
aplicaciones de Justicia. Se utiliza para la autenticación y autorización de
los usuarios.
138 de 198
Framework Atlas
Normativa
Para el framework Atlas se han definido unas “políticas de acceso” para las aplicaciones que consisten en
la definición de unas reglas de validación de acceso de los usuarios. Estas políticas indican cual es el
mecanismo de acceso, contra que repositorios se deben llevar a cabo el proceso de autenticación, así
como otras medidas a adoptar.
A continuación se muestra una tabla con la lista de políticas de acceso que se han definido para Atlas y
que se pueden utilizar en las aplicaciones web.
Política
Repositorio a validar y acciones
Público
(no se realizará ninguna acción)
Público
Certificado
Validar Certificado contra la plataforma multipki de ASF
Usuario
Intranet
Validar el usuario contra LDAP y recoger el rol de USU
Usuario
Internet
Validar Certificado (multiPKI) o validar el usuario y
recoger su rol en USUI
Usuario
Justicia
Validar Certificado (multiPKI) o validar el usuario y
recoger su rol en USUJ
Demo
Política para desarrollo en la cual no es necesario
disponer de ningún repositorio. Los usuarios de pruebas
se definen en un fichero xml.
139 de 198
Framework Atlas
Normativa
En algunas aplicaciones se puede dar el caso de que, dependiendo del entorno desde donde se acceda a
la aplicación, la forma de autenticación sea distinta. Por ejemplo: una autenticación con certificado si la
aplicación es accedida desde internet y permitir acceso mediante usuario/contraseña para los accesos
desde la intranet. El Servicio de Autenticación y Autorización de usuarios permite que dependiendo del
dominio/host al que se conecte el usuario se presente una política de acceso u otra, según se haya
definido en la aplicación a la que se está accediendo.
NORMA
SBAutenAuto
Aquellas aplicaciones web que tengan que restringir el acceso a determinados usuarios deberán
utilizar el Servicio de Autenticación y Autorización del framework Atlas y siempre utilizando alguna
de las políticas ya definidas en el mismo.
Por otra parte dentro de una aplicación determinados usuarios tendrán acceso a unas opciones y otros
usuarios a otras opciones. Esto se va a gestionar creando distintos perfiles o roles según el tipo de
usuarios y limitando el acceso a las opciones de menú y a las rutas de acceso según los perfiles creados.
NORMA
SBAutoPerfiles
Si la aplicación tiene distintos perfiles de acceso, la seguridad se debe implementar a nivel de
menú y a nivel de urls de acceso.
Para más información sobre el Servicio de Autenticación y Autorización consultar el manual
ATLAS_MUS_Servicio_Autenticacion_y_Autorizacion.
El Real Decreto 3/2010, 8 de enero, por el que se regula el Esquema Nacional de Seguridad en el
ámbito de Administración Electrónica, previsto en el artículo 42 de la Ley 11/2007, establece la política de
seguridad en la utilización de medios electrónicos por las Administraciones Públicas y estás constituido
por principos básicos y requisitos mínimos que permitan una protección adecuada en la información.
Para asegurar estos requisitos mínimos del Esquema Nacional de Seguridad en las aplicaciones
desarrolladas con el framework Atlas se han implementado los siguientes mecanismos:
·
En la pantalla de acceso al sistema, se informa, mediante un enlace a las condiciones de
acceso, al usuario de las obligaciones que implica la tenencia de un autenticador, en particular el
deber de custodia diligente, protección de su confidencialidad e información inmediata en caso de
pérdida y ha de indicar que ha leido y acepta las condiciones de acceso.
140 de 198
Framework Atlas
Normativa
·
No se ofrecen mensajes de ayuda en la ventana de conexión al sistema o durante la conexión que
den ‘pistas’. Por ejemplo: “Password incorrecta”. El mensaje cuando el usuario no existe, la
password es incorrecta o no está asociado a la aplicación es: “Las credenciales introducidas son
erróneas”.
·
No se autorellena el identificador de usuario en el sistema
·
La información de logín se validará sólo tras rellenar todos los datos de entrada
·
El sistema presenta al usuario el último acceso realizado con su identidad.
141 de 198
Framework Atlas
Normativa
·
El sistema registra los intentos de acceso exitosos y erróneos al sistema (Fecha, hora e
identificador de usuario) en un modelo de datos centralizado que permita su posterior explotación.
·
Una vez que se ha obtenido el acceso al sistema en la zona de información sobre el usuario se
muestra un enlace a un Aviso de Seguridad a partir del cual se muestra una ventana informativa
con sus obligaciones principales tras obtener el acceso (uso permitido, uso no permitido,
supervisión de la actividad, etc.)
No se pueden realizar modificaciones en las aplicaciones que impliquen la modificación o anulación de
estos mecanismos.
NORMA
SBENS
No se pueden realizar modificaciones en el control de acceso que impliquen las modificación o
anulación de los mecanismos implementados para cubrir los requisitos mínimos del Esquema
Nacional de Seguridad.
142 de 198
Framework Atlas
Normativa
8.2
COMPONENTES DE PRESENTACION
El framework Atlas ofrece un conjunto de componentes visuales para el desarrollo de las interfaces
gráficas de usuario de las aplicaciones web.
Estos componentes están basados en los siguientes productos:
·
JSF estándar
·
RichFaces
·
Ajax4JSF
·
Facelets
Los componentes que ofrece el framework Atlas son:
Componente
Descripción
Layouts
Plantillas para organizar la información dentro de la página
Componentes de Menú
Componentes para la construcción de menús en una aplicación. Existen
3 tipos de menús:
· Menú Vertical
· Menú Horizontal
· Menú Visual
Rastro de Migas
Indicador de navegación para situar al usuario en la estructura de
contenidos
Calendario
Facilita al usuario introducir una fecha en un formulario mostrando en un
panel emergente un calendario mensual.
Lista de Valores
Facilita al usuario la introducción de un valor que está asociado a un
catálogo
Lista Paginada
Muestra una lista de datos de forma tabulada en una serie de páginas
Mensaje de Error
Panel para mostrar un mensaje de error
Captcha
Ofrece el mecanismo de prueba necesario para determinar cuando un
usuario es humano o no. La prueba consiste en introducir por parte del
usuario una serie de caracteres los cuales son mostrados de forma
distorsionada por pantalla.
Número de documento
Tiene por objetivo el validar identificadores legales (DNI, CIF, Pasaporte
y Tarjeta de Residencia).
Código de Barras
Permite incrustar en una página un código de barras en diferentes
formatos.
Arbol Jerárquico
Permite mostrar un conjunto de datos organizados jerárquicamente en
forma de árbol
Arbol Accesible
Permite mostrar un conjunto de datos organizados jerárquicamente en
forma de árbol cumpliendo con la accesibilidad de las aplicaciones
Solapas
Permite mostrar una barra de solapas para organizar formularios que
incluyen muchos datos
143 de 198
Framework Atlas
Normativa
Para más información se puede consultar cada uno de los manuales de cada componente. Estos manuales
se llaman ATLAS_MUS_Componente_xxxxx
8.3
SERVICIO DE TRAZAS
El Servicio de Trazas de Atlas proporciona a todas las aplicaciones una serie de logs automáticos (Inicio
/Fin de métodos que deban ser traceados, Transacciones, SQL de las consultas, etc…) durante la
ejecución de la aplicación además de formatear todos los logs (tanto generados automáticamente por el
componente como los definidos por la propia aplicación) para su posterior uso en la Herramienta de
Monitorización.
SBTrazas
Las aplicaciones deberán generar un único log de aplicación utilizando el Servicio de Trazas que
el framework Atlas ofrece.
Se deberá hacer un uso adecuado de los niveles de prioridad para los mensajes de logs. Las
prioridades predefinidas ofrecidas son (ordenadas de mayor a menor detalle): DEBUG > INFO >
WARN > ERROR > FATAL.
Estableceremos los siguientes criterios para la explotación de los niveles de log desde nuestro
código:
·
DEBUG: Mensajes de depuración. Se puede utilizar para mostrar el valor de variables,
NORMA
parámetros de configuración, etc. Son mensajes que deberían ser entendidos y tratados
por alguien que conoce el código de la aplicación. Incorporarán información sobre
checkpoints que ayudarán a seguir el curso de la ejecución del algoritmo implementado.
·
INFO: Mensajes de información. Se utilizan para anunciar el progreso en el flujo de la
aplicación. Marcarán inicios y finalización de bloques de actividades con cómputos de
tiempo empleado en realizarlas, etc.
·
WARN: Mensajes de advertencia, usado dentro de la aplicación para dar aviso de
excepciones esperadas y que nuestro código sepa tratarlas para evitar que la aplicación
se interrumpa.
·
ERROR: Mensajes de error, para dar aviso de errores inesperados que no lleguen a
detener o afectar la ejecución de la aplicación, como por ejemplo que algún parámetro de
configuración no sea correcto y se cargue el valor por defecto del mismo.
·
FATAL: Mensajes de error, para dar aviso de errores inesperados que afectan o detienen
la ejecución de la aplicación.
144 de 198
Framework Atlas
Normativa
A continuación se muestra una figura que representa de forma piramidal la jerarquía de niveles de trazas
así como la información a mostrar.
INFO: Mensajes de información
FATAL: Mensajes de error críticos
ERROR: Mensajes de error
ØInicio-fin de acciones y uso de
componentes/servicios.
ØImplementar un sistema de alertas que avise de la caída
del sistema y dejar notificación del envío en el fichero de
log.
ØAñadirá un indicador de prioridad junto a información
relevante que ayude a comprender el alcance del error:
ØFecha, Hora, Nombre de clase, Nombre de método,
tiempo de ejecución del método.
ØSi la clase o el método accede a base de datos :
ØSentencia HQL/SQL con sus parámetros .
ØSiempre que sea posible, almacenar información detallada
sobre el error producido.
ØDeberá integrarse con los sistemas de alertas ICM
ØTiempos de preparación y/o ejecución de las
consultas.
ØNivel 1 : El proceso puede finalizar
correctamente a pesar de las inconsistencias
producidas.
ØNivel 2: Se desconoce si la finalización del
proceso puede darse por válida.
ØNivel 3: El carácter del error es severo.
ØCiclo de vida de las transacciones: inicio y fin
(commit y rollback), etc.
ØActividad del pool de conexiones
WARN: Mensajes de advertencia
ØNombre del usuario que invoca al método.
ØVolcado de errores con nivel, número y descripción.
ØVolcado de los parámetros de configuración (al
arrancar)
ØPunto del sistema donde se produzca.
FATAL
ØInformación relacionada sobre el posible impacto
ØLas trazas deberán reflejar los datos de la operación
que ha generado la excepción.
ØValores del fichero de configuración con la que se está
realizando la operación.
ERROR
NIVEL MÍNIMO
DE TRAZAS
DEBUG: Mensajes de depuración
WARN
ØInformación detallada de la ejecución de métodos:
ØEntrada y salida de un método
ØValor de parámetros
INFO
ØHechos relevantes producidos dentro de un método:
ØConstrucción y destrucción de objetos
relevantes
ØAccesos a objetos locales y remotos
DEBUG
ØCualquier otra información que permita determinar
que se esta realizando en un instante determinado
ØEl proceso detallado del flujo de invocaciones sobre toda la
infraestructura
ØInformación de llamadas entre distintas capas y componentes
del sistema
Figura 2 : Niveles de trazas
NORMA
SBTrazasSeg
El fichero de log no contendrá información que suponga riesgo de seguridad según lo establecido
por la LOPD, como por ejemplo contraseñas no cifradas, datos que identifiquen a menores,
minusvalías, etc.
145 de 198
Framework Atlas
Normativa
8.4
SERVICIO DE AUDITORIA DE SEGURIDAD
Los Sistemas de Información de la Comunidad de Madrid en algunos casos tratan datos personales de
nivel alto que son especialmente protegidos según el Real Decreto 1720/2007 - Reglamento desarrollo de
la LOPD. Algunos ejemplos de datos personales de nivel alto son:
§
Ideología, afiliación sindical, religión, creencias, origen racial, salud o vida sexual.
§
Recabados con fines policiales sin consentimiento.
§
Derivados de actos de violencia de género.
§
Tráfico y localización en operadores que prestan servicios de comunicaciones electrónicas.
En estos casos es obligado que se recoja información sobre los accesos realizados a dichos datos.
El Servicio de Auditoria de Atlas se encarga de auditar los accesos mencionados anteriormente. Para ello
es necesario que la aplicación indique cuáles son aquellos datos susceptibles de ser auditados, basándose
en los mecanismos que ofrecen los framework’s Spring e Hibernate.
El Servicio de Auditoria intercepta todas las operaciones de base de datos que se realizan a través de
Hibernate y deja el registro de la auditoria en el esquema TRAZ a través del paquete de base de datos
ATLAS.PACK.LOG.
Para más información sobre la utilización de este servicio consultar el manual
NORMA
ATLAS_MUS_Servicio_Auditoria.
SBAudit
Las aplicaciones que precisen auditar los accesos a los datos protegidos lo harán a través del
Servicio de Auditoria del framework Atlas.
146 de 198
Framework Atlas
Normativa
9
INTEGRACION
El framework Atlas para cubrir los requisitos de integración con otros productos ofrece una serie de
servicios adicionales que vamos a denominar servicios de integración.
A continuación se muestran los distintos servicios que ofrece el framework.
En el caso de que un proyecto tenga un requisito de integración con otro producto o tecnología se debe
comunicar al Area de Aplicaciones Especiales y Arquitectura de Software para que se valore la mejor
forma de realizar dicha integración.
147 de 198
Framework Atlas
Normativa
9.1
SERVICIO DE GESTIÓN DOCUMENTAL
La solución de gestión documental para las aplicaciones de la Comunidad de Madrid es el gestor de
documental de EMC Documentum.
La plataforma EMC Documentum es una extensa suite de productos para la gestión documental que
proporciona servicios para la creación, gestión, distribución y archivo de cualquier tipo de contenido
documental.
Sobre este producto se ha construido un servicio dentro del framework Atlas que permite un acceso a la
plataforma de gestión documental independiente de la solución elegida.
La integración con el gestor documental se realiza en dos ambitos:
·
Acceso al core de documentum mediante programación
·
Componentes visuales que acceden al gestor documental
Para facilitar la configuración y uso de este servicio se ha creado el arquetipo web documental por lo tanto
los módulos web que necesiten acceder a este servicio deberían partir de este arquetipo.
Por otra parte en los proyectos que incluyen gestión documental es necesario crear un módulo que las
definiciones de los tipos documentales y demás elementos necesarios. Para más información sobre este
tipo de módulos consultar el manual ATLAS_MUS_Servicio_Gestion_Documental, y
ATLAS_MUS_Arquetipo_Web_Documentum.
NORMA
SIGDOC
Las aplicaciones que necesiten acceder a un gestor documental lo harán a través del Servicio de
Gestión Documental y accediendo a través de los servicios web implementados dentro de este
servicio. Actualmente este Servicio de Gestión Documental se ha implementado sobre
Documentum.
148 de 198
Framework Atlas
Normativa
9.2
SERVICIO DE PLANIFICACION
En ocasiones es necesario ejecutar ciertas tareas a una hora concreta, en base a una planificación
preestablecida. Tal es el caso de la ejecución de informes periódicos, o la generación de estadísticas. Este
tipo de tareas suele conllevar una carga importante para la base de datos, cosa que puede empeorar el
rendimiento de la aplicación (y de otros sistemas).
Para este tipo de tareas normalmente pesadas, existe una solución simple: planificar la creación del
informe para las horas cuando el sistema tiene menor carga de trabajo. La solución elegida para realizar la
planificación de las tareas mencionadas anteriormente es el producto de BMC CONTROL-M.
Figura 3 : Planificación de tareas con Control-M
Para poder invocar a este tipo de tareas necesitamos crear un módulo batch que implementa la tarea a
ejecutar y utilizar el Servicio de planificación para ejecutar o planificar la tarea.
NORMA
El Servicio de Planificación ofrece os siguientes elementos:
·
Acceso al api de ControlM mediante programación
·
Componentes visuales que muestran información obtenida de ControlM
SIPLAN
Las aplicaciones que necesiten invocar una tarea batch lo harán a través del Servicio de
Planificación del framework Atlas.
149 de 198
Framework Atlas
Normativa
9.3
SERVICIO DE CRIPTOGRAFIA
Las aplicaciones de la Comunidad de Madrid muchas veces requieren de la utilización de certificados
digitales y/o operaciones criptográficas que posibilitan la tramitación electrónica.
NORMA
El Servicio de Critografía, provee las siguientes funcionalidades:
·
Cifrado y descifrado de datos
·
Firma electrónica en servidor
·
Verificación de firmas electrónicas
·
Validación de certificados digitales
·
Obtención de datos de un certificado
SICert
Las aplicaciones que necesiten realizar operaciones con certificados digitales y/o criptográficas lo
harán a través del Servicio de Criptografía que ofrece el framework Atlas.
Para más información sobre el uso del servicio de certificados digitales consultar el manual
ATLAS_MUS_Servicio_Criptografia.
150 de 198
Framework Atlas
Normativa
9.4
SERVICIO DE BUSSINESS INTELLIGENT
La solución de Bussiness Intelligent para los proyectos de la Comunidad de Madrid es Bussiness Objects
de SAP. Sobre este producto se han definido dentro del framework Atlas una serie de componentes
visuales que permite un acceso directo a la plataforma de Bussiness Objects.
Business Objects XI ofrece, en una única solución, funciones de gestión de rendimiento, generación de
informes, consulta y análisis e integración de datos, apoyando a una correcta toma de decisiones tanto a
nivel ejecutivo y directivo como a nivel estratégico. Integra distintas fuentes de datos, abstrayendo dichas
fuentes, así como los modelos subyacentes, creando una capa semántica con entidades entendibles para
el usuario ejecutor y consumidor de los informes, sin necesidad de conocer los modelos de datos
relacionales. Esta capa semántica es lo que se conoce en Business Objects XI por el concepto de
Universo.
Business Objects XI es un producto completamente autónomo y completo que unifica todo el ciclo de
gestión y producción de informes. Las principales características aportadas por Business Objects XI son:
l
Acceso y presentación de datos en diversos formatos.
l
Integración de múltiples fuentes de datos.
l
Abstracción de las fuentes de datos en un conjunto de entidades entendibles por parte del usuario
que realiza los informes. Esta abstracción permite que los usuarios que realmente tienen
necesidad de extraer información, puedan realizar informes sin necesidad de tener los
conocimientos técnicos necesarios para comprender el modelo de datos subyacentes.
l
Modificación y creación de reportes en tiempo de ejecución.
l
Gestión eficiente y segura de reportes críticos para el negocio.
l
Entrega de la información requerida a la gente adecuada en un momento determinado.
l
Basado en un tecnología fuertemente probada.
l
Escalabilidad y rendimiento adaptables en base al crecimiento del negocio.
l
Soporte a distintos lenguajes de programación.
l
Gestión de la seguridad en todos los niveles.
Las siguientes tareas del ciclo de vida de generación de informes se deben realizar con las aplicaciones
aportadas por el producto Business Objects XI:
l
Tareas de extracción, transformación y carga (ETL).
l
Definición de Universos.
l
Organización en carpetas y subcarpetas.
l
Definición de usuarios y permisos a nivel de datos, de carpetas y de informes.
l
Creación de informes.
l
Planificicación de informes.
La integración con Business Objects XI de las aplicaciones desarrolladas con Atlas se limitará a las
siguientes tareas:
151 de 198
Framework Atlas
Normativa
l
Conexión al servidor Business Objects XI con las credenciales definidas en la implantación BO.
l
Recorrido de carpetas autorizadas.
l
Visionado de los informes de esas carpetas.
l
Planificación de informes
En proyectos que integren una solución completa de Business Objects XI, el ciclo de vida de la extracción
de información se gestionará por medio de las aplicaciones que proporciona la plataforma Business
Objects XI, y no desde la integración con Atlas. La integración con Atlas se limitará a la presentación,
NORMA
visionado y planificación de los informes generados por la plataforma Business Objects XI.
SIBI
Las aplicaciones que necesiten acceder a la plataforma de Bussiness Objects lo harán a través de
los componentes establecidos en el framework Atlas.
152 de 198
Framework Atlas
Normativa
9.5
SERVICIO DE INVOCACIÓN DE SERVICIOS WEB
Muchas de las aplicaciones que se desarrollan para la Comunidad de Madrid necesitan acceder a servicios
web tanto servicios que se han desarrollado específicamente para la tramitación electrónica como otros
servicios web que incluso pueden estar fuera de nuestros entornos.
Dada la amplia variedad de tipos de servicios web que nos podemos encontrar y los distintos tipos de
seguridad que nos pueden requerir los citados servicios web se ha desarrollado el Servicio Invocador de
Servicios.
En el caso de que el servicio a utilizar se haya desarrollado con Atlas se ha de acceder utilizar el cliente
Atlas que proporciene el servicio web.
NORMA
NORMA
Para más información sobre este servicio consultar el manual ATLAS_MUS_Servicios_Web.
INTWS
Para invocar a un servicio web se hará mediante la utilización del Servicio de Invocación de
Servicios Web de Atlas.
INTNomClient
Para facilitar su localización el nombre del paquete donde se incluyan las clases generadas por el
invocador de servicios debe contener la palabra client.
153 de 198
Framework Atlas
Normativa
9.6
SERVICIO DE PROCESOS DE NEGOCIO
Un proceso de negocio es la representación del trabajo realizado por las personas y los sistemas de una
organización, con el objetivo de ofrecer un servicio a sus clientes. Business Process Management (BPM)
es el arte de formalizar la automatización de los procesos de negocio.
Un BPM simplifica el desarrollo de aplicaciones que tengan alguno de los siguientes requerimientos:
·
Orquestación de servicios de negocio: es la secuenciación de las diferentes tareas y servicios
que forman parte de un proceso. La orquestación permite crear lógica dentro del proceso,
ofreciendo funcionalidades tales como:
o
Invocación sincrónica y asincrónica a servicios.
o
Manejo de transacciones.
o
Mecanismos de compensación y manejo de excepciones.
o
Transformación de mensajes para adaptar la salida de un servicio a la entrada de otro
(mapeo de datos).
o
Manejo de condicionales, loops, etc.
o
Orientación a flujos de trabajo: los BPM ofrecen herramientas para definir los procesos de
negocio que comprenden un sistema. Los procesos de negocio pueden comprender tareas
desempeñadas por personas, y tareas que se ejecutan de forma automática.
·
Integración de personas dentro de los flujos de trabajo: cuando la ejecución de un proceso
requiere que ciertas personas en la organización realicen funciones relacionadas con el proceso
(aprobaciones, revisiones, etc.), el uso de un BPM simplifica la interacción con las mismas.
·
Necesidades de integración con diferentes sistemas y fuentes de datos: los BPM disponen de
conectores para acceder a diferentes sistemas comerciales existentes en grandes organizaciones
(SAP, PeopleSoft, CICS, etc.), de forma que la creación de tareas en las que intervenga este tipo
de productos se simplifica enormemente.
·
Capacidades de seguimiento y gestión de las tareas definidas en los procesos de negocio:
un BPM ofrece herramientas administrativas que permiten a ciertas personas poder hacer un
seguimiento de los procesos y tareas que los comprenden.
·
Medición, auditoría, control y reportes: asociado a un producto de este tipo se ofrecen
herramientas para realizar métricas y análisis del funcionamiento global del sistema.
·
Aplicación de reglas de negocio.
·
Ejecución de procesos con estado.
154 de 198
Framework Atlas
Normativa
La solución de BPM (procesos de negocio) para las aplicaciones de la Comunidad de Madrid es producto
Oracle BPM. Sobre este producto se ha construido un servicio dentro del framework Atlas que permite un
acceso a la plataforma de BPM independiente de la solución elegida, este servicio se denomina Servicio
de Procesos de Negocio.
La integración con el motor de procesos se realiza en dos ambitos:
·
Acceso al core de Oracle BPM mediante programación
·
Componentes visuales que muestran información obtenida del motor de procesos
NORMA
SIBPM
9.7
Las aplicaciones que necesiten acceder a un motor de procesos lo harán a través del Servicio de
Procesos de Negocio de Atlas. Actualmente este Servicio de Procesos de Negocio se ha
implementado sobre el producto Oracle BPM.
OTRAS SOLUCIONES
Por otra parte dentro del framework Atlas se ha seleccionado una serie de soluciones o librerías de
terceros que nos cubren otras funcionalidades o requisitos que podamos tener a la hora de desarrollar
NORMA
nuestra aplicación.
SOLLIB
El uso de cualquier librería, producto de terceros o tecnología no incluido dentro del framework
deberá ser previamente consensuado y autorizado por ICM.
155 de 198
Framework Atlas
Normativa
9.7.1
REPORTING
La solución de generación de listados e informes para las aplicaciones de la Comunidad de Madrid es
Crystal Reports 2008.
Para utilizar informes de Crystal Reports 2008 en las distintas aplicaciones de la Comunidad de Madrid, se
ha optado por una solución centralizada que libera a la aplicación que va a utilizar los informes de la
complejidad de su generación e interpretación.
Para obtener más información sobre el uso de informes con Crystal Reports consultar el manual
ATLAS_MUS_Arquetipo_Web.
Para incluir informes en nuestra aplicación en primer lugar debemos diseñar o crear dichos informes con la
herramienta Crystal Reports 2008.
SOLRpt
NORMA
La herramienta de creación de los informes de las aplicaciones será Crystal Reports 2008.
El nombre del informe tendrá la siguiente nomenclatura:
XXXXNombreDelInforme.rpt
Donde xxxx es el nombre del proyecto y NombreDelInforme el nombre del informe que debe estar
escrito en minúsculas, excepto la primera letra de cada palabra que estará en mayúsculas. Este
nombre no puede contener espacios en blanco. La extensión debe ser rpt.
La conexión con la base de datos deberá ser JDBC y desde la propia herramienta se puede ejecutar el
informe para ver el resultado del mismo.
SOLRptConex
El tipo de conexión con la base de datos debe ser JDBC.
NORMA
Los informes se desarrollarán integrando las sentencias SQL dentro del informe, no estando
permitidas las opciones de ResultSet, RecordSet ni colecciones de objetos, a no ser que así se
acuerde explícitamente con ICM.
El nombre de las tablas de base de datos dentro del informe rpt desarrollado no deberán incluir el
nombre de la instancia de base de datos. De esta forma será posible ejecutar los informes sobre
distintas instancias (desarrollo, test, producción...) sin necesidad de modificar el fichero rpt.
Una vez que tengamos los informes completados se deberán publicar en la plataforma de BO. En la
entrega se agruparan los distintos informes dentro de un nuevo módulo de tipo reports.
156 de 198
Framework Atlas
Normativa
NORMA
SOLRptModulo
Todos los informes se entregaran en un módulo con la siguiente nomenclatura:
xxxx_crbo
Donde xxxx es el nombre del proyecto.
Dentro se creará una carpeta llamada reports donde se incluirán todos los reports.
SOLRptConf
NORMA
El fichero de configuración environment.properties debe incluir las siguientes variables:
·
bo_ws.webservice – Apunta a la url del servicio web bo_ws para autenticación
·
bo_ws.rutabo – Servidor de la plataforma BO (Ej: http://icmdesbi01:8080)
·
bo_ws.usuario – Usuario con el que nos conectaremos a la plataforma de Bussiness
Objects.
·
bo_ws.clave – Clave del usuario encriptada.
157 de 198
Framework Atlas
Normativa
9.7.2
COMPOSICION DE DOCUMENTOS
Este punto tiene por objetivo explicar como se realizará la generación dinámica de documentos Word y
RTF, a partir de plantillas previamente definidas en este mismo formato. Para el relleno de las plantillas así
como la transformación dinámica de las mismas se utilizará Velocity.
Velocity es un motor de plantillas basado en Java que incluye un lenguaje de script, el Lenguaje de
Plantillas de Velocity (VTL por sus siglas en inglés). El Lenguaje de Plantillas de Velocity (VTL) nos permite
incorporar contenido dinámico dentro de un documento de tipo texto de una manera fácil y sencilla. Este
lenguaje se utilizará para la creación de las plantillas.
Desde la parte del negocio de la aplicación es dónde se va a realizar la fusión de las plantillas utilizando el
API Java de Velocity. Se trata de que la fusión del documento se realice en el lado del servidor. El uso del
API en java básicamente consiste en definir un contexto con las variables a mapear en el documento,
aplicar este contexto a la plantilla y generar el nuevo documento.
Documentos RTF
Contenedor Web
.doc, .rtf
Petición JSF
Documento
generado
Documento
generado
Plantilla Velocity
VTL
.html, txt, etc
Documento
origen
Respuesta JSF
DOCUMENTUM
.doc, .rtf
Motor de plantillas
velocity
Figura 4 : Generación de documentos RTF
NORMA
SOLCompositor
Para la composición de documentos en Atlas se utilizará la solución de Velocity.
Las plantillas se crearán en formato RTF y los documentos generados tendrán también formato
RTF. Las plantillas se incluirán en la carpeta “plantillas” del proyecto.
BUENAS PRACTICAS
SOLCompositor
·
Se recomienda utilizar nombres significativos en las variables, y notaciones sencillas al hacer
uso de las etiquetas que dote de claridad a la plantilla y sea fácilmente inteligible mediante
una lectura rápida. Esto ayudará a realizar un buen mantenimiento de la misma cuando sea
necesario aplicarla modificaciones.
·
Se recomienda utilizar sintaxis de etiquetas simple, escapando de notaciones más complejas
a no ser que esté justificada claramente su utilización.
·
Se recomienda no anidar bucles en la medida de lo posible. Estos procesos interactivos
158 de 198
Framework Atlas
Normativa
complican los procesos de renderizado.
·
Se recomienda hacer uso de las estructura de datos estándar: string, list y map. Su procesado
es rápido y eficaz.
·
Se recomienda incorporar macros a las plantillas cuando se prevea una reutilización del
mismo en varios puntos del documento o cuando la operación de renderizado se presuponga
compleja. En este último caso el macro deberá mostrar una interfaz clara en su llamada que
aporte la máxima claridad a la plantilla.
·
Se recomienda escapar de utilizar llamadas a macros de manera recursiva.
·
Se recomienda delegar el menor trabajo posible al generador de documentos. A pesar de que
incorporan cierta potencia de calculo, operaciones y operadores, manejo avanzado de
estructuras de datos, etc… prescindir cuando sea posible de ello, delegando esos cálculos a
nuestra aplicación y dejando que el compositor de documentos sólo realice la tarea de
renderizado, la de “dibujar” el documento, es decir los datos que alimentan la plantilla, deben
de ir adecuadamente tratados y formateados.
159 de 198
Framework Atlas
Normativa
9.7.3
GESTION DE DOCUMENTOS EXCEL
NORMA
La solución del framework Atlas para la generación o modificación de ficheros Excel es Jakarta POI.
SOLExcel
Para la gestión de documentos Excel en las aplicaciones del framework Atlas se utilizará la librería
Jakarta POI.
Desde las aplicaciones se usuará directamente este API desde la capa de negocio.
160 de 198
Framework Atlas
Normativa
9.7.4
GESTION DE DOCUMENTOS PDF
Para la generación y manipulación dinámica de PDFs se deberá utilizar la librería iText.
Se debería utilizar esta librería en casos como:
·
Generación dinámica de documentos PDF mediante APIs de desarrollo en base a varias
NORMA
alternativas de fuentes de datos como bases de datos, ficheros XML, etc.
·
Crear mapas, libros electrónicos, dotar de interactividad a documentos PDF.
·
Añadir bookmarks, números de página, filigranas, etc.
·
Dividir y concatenar documentos pdf.
SOLPDF
Para la generación de documentos PDF desde las aplicaciones del framework Atlas se utilizará la
librería IText.
A pesar de que iText permite la generación de documento RTF, para esta finalidad ha de emplearse
Velocity, ya que es un mecanismo más flexible y potente.
161 de 198
Framework Atlas
Normativa
9.7.5
GENERACION DE GRAFICOS
Para la generación de gráficos se utilizará la librería JFreeChart, una librería 100% Java que permite
desarrollar gráficos, para poder incluirlos en aplicaciones, documentos e informes. Con JFreeChart
podremos hacer diferentes tipos de gráficos que van desde los tipos comunes tales como gráficos
circulares , gráficos de barras , áreas , gráficos de línea , histogramas , diagramas de Gantt y más
específicos y menos frecuentemente utilizados como tipos Candlestick, Viento y Wafer Map.
También se puede usar la familia Chart de Jenia4faces, que ofrece componentes JSF para la inclusión de
gráficas realizadas mediante JFreeChart en una aplicación JSF.
NORMA
SOLGraficos
La generación de gráficos de las aplicaciones del framework Atlas se hará con la librería
JFreeChart y los componentes visuales Jenia4Faces.
PRACTICA
BUENA
SOLGraficosGrandes
Como norma general se recomienda tener especial cuidado con imágenes de JFreeChart que
ocupen mucho espacio y puedan saturar el ancho de banda en aplicaciones con interfaz Web.
162 de 198
Framework Atlas
Normativa
9.7.6
MANIPULACION DE ARCHIVOS MULTIMEDIA
En muchas ocasiones surge la necesidad de utilizar un API que permita la incorporación de archivos audio,
video, sonido u otro tipo de archivos multimedia en aplicaciones Java, extendiendo las capacidades
multimedia por defecto de la plataforma Java 2 Standard Edition.
La tecnología Java Media FrameWork API (JMF) permite manipular y gestionar ficheros de audio, video u
otros archivos multimedia que formen parte integral de aplicaciones y applets. Este paquete opcional actúa
sobre múltiples formatos, proporcionando a desarrolladores un control adicional escalable e independiente
de la plataforma de proceso y renderizado de archivos multimedia.
JMF esta diseñada en base a plugins proporcionando acceso directo a recursos multimedia y aportando a
JMF las caracteríticas necesarias para personalizarlo y extenderlo en base a necesidades específicas.
SOLMultimedia
El API JMF 2.X será la tecnología a utilizar para cualquier manipulación sobre archivos
NORMA
multimedia. Este API no esta incluida por defecto en la plataforma Java 2 Standard Edition.
Cuando se necesite extender las capacidades de la tecnología JMF en referencia a la
manipulación de ficheros de imagen se podrá recurrir a las API’s Java 2D, Java advanced Image
(JAI) y JAI Image I/O.
Se deberá utilizar el API Java 3D cuando se requieran capacidades adicionales sobre
manipulaciones y renderizados de imágenes en tres dimensiones.
163 de 198
Framework Atlas
Normativa
9.7.7
Acceso a plataforma y dispositivos locales
La plataforma local define los elementos, herramientas, servicios y productos residentes en la máquina de
cada usuario para dar soporte a la ejecución de las aplicaciones de la organización cubriendo la extensión
de las aplicaciones web de cara a interactuar con elementos residentes en la plataforma local, como
NORMA
pueden ser dispositivos y aplicaciones.
SOLAccesoLocal
Para la integración con los dispositivos y aplicaciones de la plataforma local se utilizarán y
desarrollarán componentes de tipo Applet.
164 de 198
Framework Atlas
Normativa
9.7.8
XML Sólo lectura
Si una aplicación necesita leer ficheros XML (sólo leer) se podrá usar la librería XPath del paquete
javax.xml.xpath
La clase de ayuda de Altas atlas.core.seguridad.util.XmlUtil tiene varias funciones para
ayudar a leer ficheros XML con unas pocas instrucciones.
Ejemplo de lectura de XML
String xml = "...";
Document xmlDocument = XmlUtil.toDomDocument(xml);
String cdDocumento = XmlUtil.evaluateXpathToString("/salida/codigoDocumento",
xmlDocument);
NodeList listaNodos = XmlUtil.evaluateXpathToNodeList(
"/salida/listado_interesados//interesado", xmlDocument);
9.7.9
XML Lectura y Escritura
Algunas aplicaciones necesitan gestionar ficheros XML. Para facilitar la gestión de los mismos se utilizará
la librería JAXB. JAXB aporta una forma sencilla de asociar un esquema XML a su representación en
código Java. Esto hace simple el manejo de datos XML desde Java, sin necesidad de conocer mucho
acerca de XML.
JAXB consta de 3 componentes principales:
·
El compilador de esquema, que transforma el esquema en una serie de elementos requeridos
para el proceso de lectura (unmarshalling) y escritura (marshalling) de un XML.
·
El generador de esquema, que convierte estos elementos (descritos mediante anotaciones Java)
a un esquema XML.
·
El framework de asociación (binding), que ofrece las operaciones de lectura (unmarshalling) y
escritura (marshalling) para el acceso, manipulación y validación de contenido XML usando los
elementos generados mediante las herramientas anteriores.
El siguiente esquema muestra un diagrama de funcionamiento de estos elementos:
165 de 198
Framework Atlas
Normativa
NORMA
SOLXML
Cuando las aplicaciones necesiten generar ficheros XML, se utilizará la implementación de
referencia de JAXB (Java Architecture for XML Binding).
Para facilitar su localización y que la herramienta de validación no de errores las clases generadas
por jaxb se incluirán en un subpaquete llamado “jaxb”.
Los pasos para realizar la asociación entre un documento XML y un objeto Java con JAXB son los
siguientes:
1. Generar las clases Java (a partir del esquema XML). Recordar que se deben incluir en un
subpaquete llamado “jaxb” de alguno de los paquetes de nuestra aplicación.
2. Compilar las clases.
3. Leer el documento origen (unmarshall).
4. Generar el árbol de contenido. El proceso de lectura genera un árbol de contenido a partir de las
clases generadas.
5. Validar: antes de generar el árbol de contenido a partir del XML origen se puede validar dicho
documento. También se puede validar el documento a generar (cuando sea el caso).
6. Procesar el contenido. La aplicación cliente puede modificar los datos del documento XML que
representa el árbol de contenido a través de los interfaces generados por el compilador
7. Escritura (marshall), esto es, generar uno o más documentos XML a partir del árbol de contenidos.
Como se dijo anteriormente, el contenido puede ser validado antes de este proceso.
La siguiente imagen muestra de forma gráfica el proceso descrito:
166 de 198
Framework Atlas
Normativa
Figura 5 : Asociación de un documento XML con un objeto Java
167 de 198
Framework Atlas
Normativa
9.7.10 ENVIO DE CORREO
El framework Spring ofrece una librería de utilidad para enviar correos electrónicos abstrayendo al usuario
de la configuración específica para cada sistema de mensajería, responsable del manejo de recursos a
bajo nivel que normalmente ha de implementar el cliente.
NORMA
SOLCorreo
Para el envío de correo desde las aplicaciones se empleará la utilidad de envío de correo que
aporta el framework de Spring.
Dicha utilidad permite el envío de correo de una forma sencilla mediante JavaMail, realizando la
configuración mediante inyección de dependencias.
En primer lugar hay definir los parámetros de configuración del environment.properties. Los parámteros
host, user y pass son obligatorios, el resto son opcionales y se usan para las plantillas de los correos.
environment.properties
# correo electronico
email.smtp.host=mail.madrid.org
email.smtp.user=PENDIENTE
email.smtp.pass=PENDIENTE
# plantilla email
email.from=icm_dga_soporte_arquitectura@madrid.org
email.subject=Ejemplo de correo para cursos
Seguidamente hay definir y configurar el bean de Spring para enviar correos.
Bean encargado del envio de correos
<!-- Bean para el envio de correos -->
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host"><value>${email.smtp.host}</value></property>
<property name="username"><value>${email.smtp.user}</value></property>
<property name="password"><value>${email.smtp.pass}</value></property>
</bean>
Se crearán plantillas para las distintas tipologías de correo electrónico que la aplicación envíe. De esta
forma no será necesario escribir en el código aspectos como el destinatario, el asunto, etc.
Ejemplo de bean de mensaje
<!--
Plantilla para enviar correo de ejemplo -->
168 de 198
Framework Atlas
Normativa
<bean id="plantillaCorreoCursos"
class="org.springframework.mail.SimpleMailMessage">
<property name="from"><value>${email.from}</value></property>
<property name="subject"><value>${email.subject}</value></property>
</bean>
Para hacer uso de los beans inyectados anteriormente, simplemente se declararán los atributos
respectivos en el servicio, con sus métodos set correspondientes.
Ejemplo de bean de servicio que envía correo
<bean id="cursosService" class="ejpl.gestion.services.CursosServiceImpl">
<property name="mailSender"><ref bean="mailSender"/></property>
<property name="message"><ref bean="plantillaCorreoCursos"/></property>
<bean>
Ejemplo de envio de correo
.....
private MailSender mailSender;
private SimpleMailMessage mailMessage;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setMailMessage(SimpleMailMessage mailMessage) { this.mailMessage =
mailMessage;
}
public void sendCourseEnrollmentReport() {
Set courseList = courseDao.findAll();
SimpleMailMessage message =
new SimpleMailMessage(this.mailMessage);
StringBuffer messageText = new StringBuffer();
messageText.append("Los cursos son los siguientes:\n\n");
for(Iterator iter = courseList.iterator(); iter.hasNext(); )
{
Course course = (Course) iter.next();
messageText.append(course.getId() + " ");
messageText.append(course.getName() + " ");
int enrollment = courseDao.getEnrollment(course);
messageText.append(enrollment);
}
message.setText(messageText.toString());
169 de 198
Framework Atlas
Normativa
msg.setTo(…);
try
{
mailSender.send(message);
} catch (MailException e) {
….
}
}
.....
Cuando el contenido de los correos electrónicos manejados por la aplicación sea complejo, se empleará el
mecanismo de plantillas que ofrece Velocity para crear plantillas avanzadas para envío de correo
electrónico. Estas plantillas se podrán crear en formato HTML y se almacenaran en la carpeta
“src/main/resources/plantillas”.
Ejemplo de plantilla de correo
<html>
<body>
<h3>Hi ${user.userName}, welcome to the Chipping Sodbury On-the-Hill message
boards!</h3>
<div>Your email address is
<a href="mailto:${user.emailAddress}">${user.emailAddress}</a>.
</div>
</body>
</html>
De esta forma se pueden crear plantillas de correo mediante cualquier editor (por ejemplo, con un editor de
HTML), y definir variables que se establecerán en tiempo de ejecución para el mensaje de correo.
Para usar Velocity desde un servicio Spring, simplemente se le ha de pasar mediante inyección de control
el bean de Spring que maneja el motor de Velocity, y usarlo en el código de envío de correo de la forma
tradicional:
Bean de Spring para Velocity
<bean id="velocityEngine"
class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<value>resource.loader=class
170 de 198
Framework Atlas
Normativa
class.resource.loader.class=
org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
Para enviar el mensaje, ahora es necesario hacer uso de un mensaje MIME (estamos enviando un mail en
HTML), para lo cual usamos el interfaz de MimeMessagePreparator de Spring:
Ejemplo de envio de correo con plantilla personalizada
private void sendConfirmationEmail(final User user) {
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
message.setTo(user.getEmailAddress());
message.setFrom("from@email.com");
// Se establecen los campos a mapear en el correo
Map model = new HashMap();
model.put("user", user);
String text = VelocityEngineUtils.mergeTemplateIntoString(
velocityEngine, "plantillas/correo.vm", model);
message.setText(text, true);
}
};
this.mailSender.send(preparator);
}
}
NOTA
Para una explicación más detallada de integración del servicio de correo de Spring en Atlas consulte el
Manual de Usuario de Envío de Correos Electrónicos.
171 de 198
Framework Atlas
Normativa
9.7.11 ENVIO DE SMS
La Comunidad de Madrid dispone de una plataforma desarrollada por Telefónica Soluciones para el envío
y recepción de mensajes SMS, que recibe el nombre de MenTeS (Mensajería de Telefónica Soluciones).
Sobre esta plataforma se ha desarrollado un servicio web que ofrecerá una interfaz estándar para el
acceso a estas funcionalidades desde cualquier tipo de aplicativo.
El siguiente diagrama muestra la arquitectura del sistema:
Figura 6 : Arquitectura de la plataforma de SMS
Para el envío de mensajes SMS se utilizará el servicio de envío de SMS que invoca a los servicios web .
Para más información consultar el manual ATLAS_MUS_Servicio_Envio_SMS.
172 de 198
Framework Atlas
Normativa
9.7.12 VISOR DE MAPAS
Dentro del framework Atlas se ha incorporado un componente visor de mapas permite mostrar mapas de
GIS y operar con ellos en aplicaciones Atlas. Tiene las siguientes características:
·
Permite personalizar el tamaño del marco en el que se muestra el mapa.
·
Dos modos de renderizado: en un marco en pantalla o en un panel popup.
·
Personalización del mapa y los componentes que lo forman mediante la modificación de
los ficheros de configuración de GIS.
A continuación se muestra un ejemplo del componente en modo popup:
Para más información consultar el manual ATLAS_MUS_Componente_Visor_Mapas.
173 de 198
Framework Atlas
Normativa
9.7.13 SERVICIOS WEB
La invocación y generación de servicios web de ATLAS se basa en los siguientes elementos:
·
Axis2
·
Módulo de seguridad Rampart
·
Módulo de seguridad para webservices de ATLAS
·
Plataforma multipki ASF
Para la creación de nuevos servicios web se partirá de un arquetipo específico para servicios web.
Los servicios web desarrollados implementaran además del propio servicio web una librería cliente para
dicho servicio que facilitará la integración de este servicio web en otros proyectos Atlas. Para más
información consultar el manual ATLAS_MUS_Servicios_Web.doc.
Los servicios web que tengan que implementar seguridad lo harán según el estandar de WS Security que
incluye la seguridad en el propio mensaje SOAP. Dentro de este modelo de seguridad existen las
siguientes posibilidades:
-
Firmado digital del mensaje SOAP – Garantiza la procedencia del mensaje, integridad de los
datos y no repudio.
-
Cifrado del mensaje SOAP – Garantiza la confidencialidad del mensaje.
Ambas posibilidades se pueden combinar.
Se puede realizar el control de acceso sobre el cliente que ha firmado el mensaje. Al cifrar el mensaje no
es necesario cifrar el canal de comunicación.
NORMA
WSSECURITY
Cuando el servicio web que se desarrolle tengan que implementar seguridad lo hará con WS
Security con los mecanismos de firma y/o cifrado de mensaje SOAP. Cualquier otro tipo de
seguridad ha de ser autorizado previamente por la Unidad de Arquitectura de Aplicaciones.
174 de 198
Framework Atlas
Normativa
10
HERRAMIENTAS
El framework ATLAS ofrece principalmente dos herramientas de apoyo al desarrollo de
aplicaciones que aseguran la calidad de los desarrollos realizados, y que se describen en los siguientes
apartados.
10.1 VALIDACION DE NORMATIVA
La comprobación del cumplimiento de la normativa ATLAS en un módulo técnico se realiza a través del
servicio SAVT y tiene como objetivo principal la comprobación del cumplimiento de la normativa Atlas
sobre un proyecto o módulo. Este servicio realiza las siguientes comprobaciones sobre los tipos de recurso
de un proyecto:
·
Valida las clases java.
·
Valida los ficheros de configuración.
·
Valida la estructura de directorios.
Dicha herramienta está implementada como un plugin que ya viene preinstalado y correctamente
configurado con los arquetipos de Atlas para su ejecución directa a través de ciertas etiquetas de
Maven.
PRACTICA
BUENA
VALFrecuente
Se deberá ejecutar la revisión de codigo semanalmente desde el inicio del proyecto (no sólo al
final del proyecto) con el fin de evitar que los incumplimientos de la normativa se vayan
acumulando a lo largo del desarrollo y esto suponga carga adicional de trabajo.
No es posible automatizar la comprobación de todas las normas, lo que no significa que el
proveedor no deba cumplirlas. Por lo tanto es posible que durante el desarrollo de la aplicación
aparezcan nuevas versiones de la herramienta de validación. Estas nuevas versiones en ningún caso
incluirán validación de nuevas normas sino que podrán validar normas ya definidas en la versión del
framework pero que anteriormente no se estaban validando (y por tanto el proveedor ya debería estar
cumpliendo, independientemente de que anteriormente la herramienta las validase o no).
Por todo lo anteriormente indicado, el hecho de que el servicio SAVT no indique errores en un
proyecto no implica que dicho proyecto cumpla al 100% con todas las normas de la normativa del
framework, aunque sí asegura un porcentaje alto de cumplimiento.
Existen casos excepcionales en los que ICM autoriza previamente que no se le aplique alguna de las
normas. Estos casos deben ser autorizados utilizando la solicitud correspondiente que firmará el Área de
175 de 198
Framework Atlas
Normativa
Aplicaciones Especiales y Arquitectura de software. Esta autorización deberá ser incluida en la solicitud de
revisión de codigo.
VALEXCLUDE
NORMA
Toda autorización excepcional a alguna norma de la normativa debe estar previamente autorizada
por ICM.
La solicitud de autorización se hará mediante el formulario de autorización correspondiente y una
vez firmado por el Área de Aplicaciones Especiales y Arquitectura de Software será incluido en la
documentación del proyecto.
En las entregas se deberá informar en la ficha de entrega sobre la autorización.
Para más información sobre el uso del servicio SAVT consultar la Guía de Calidad en:
http://intranet.madrid.org/arquitecturasw/calidad/servicios
10.2 REVISION DE CODIGO ESTATICO
Un estándar de codificación adecuado y buen diseño orientado a objetos son prácticas que deben estar
presentes en todos los proyectos.
Es necesario imponer una normalización a la hora de desarrollar código debido a diferentes factores que
facilitarán el mantenimiento posterior y costes económicos derivados de tal actividad.
• Un porcentaje elevado del coste del software va asociado a su mantenimiento.
• Las aplicaciones son dinámicas, crecen y se modifican, requieren de mantenimiento y
evolución.
• Las convenciones de código nos facilitarán la interpretación fácil de nuestro código, más rápida y
más clara.
• Debemos pues garantizar el cumplimiento con estas convenciones.
Para todos los desarrollos en Java con el framework Atlas se deben utilizar las convenciones de código
para el lenguaje de programación Java de SUN Microsystems. Estas convenciones están disponibles en la
url: http://java.sun.com/docs/codeconv/
El uso de convenciones de código se debe realizar desde la primera linea de código que se implemente y
no esperar a que se haya finalizado el desarrollo ya que en este caso el coste del cambio es muy elevado.
La herramienta Eclipse nos permite mediante determinados plugins validar que se estan cumpliendo estas
convenciones. Dentro del framework Atlas se han personalizado los ficheros de reglas para que se realicen
las validaciones que el framework requiere.
176 de 198
Framework Atlas
Normativa
La validación se debe realizar según se van codificando las clases. En el caso de que ya tengamos código
desarrollado y queramos ajustarlo a esta codificación Eclipse dispone de utilidades que nos permiten
formatear el código para que se cumplan muchas de las reglas que se validan.
Las herramientas que se van a utilizar para la validación son:
Herramientas
URL
Code Style Formatter de Eclipse
Incluido en eclipse
Code Style Clean up de Eclipse
Incluido en eclipse
Plugin de Checkstyle
http://eclipse-cs.sourceforge.net/
Plugin de PMD
http://pmd.sourceforge.net/
PMD: Conjunto de reglas basadas en el análisis de código Java que identifica problemas como código
muerto, posibles bugs, etc...
Checkstyle: Herramienta para el análisis estático de código usado para chequear que el código fuente
Java cumple con unas reglas de codificación determinadas.
El framework proporciona los siguientes ficheros de reglas:
Fichero
Descripción
ATLAS_JAVA_CC_CS.xml
Fichero con las reglas de checkstyle del
framework Atlas
ATLAS_JAVA_CC_PMD.xml
Fichero con las reglas de pmd del framework
Atlas
ATLAS_JAVA_CC_ECLIPSE_CLEANUP_PROFILE.xml
Fichero con las opciones para la utilidad de
cleanup de Eclipse
ATLAS_JAVA_CC_ECLIPSE_FORMATTER_PROFILE.xml Fichero con las opciones para la utilidad de
formatter de Eclipse.
Para más información sobre el uso de estas utilidades consultar el manual
ATLAS_MUS_Preparacion_Entorno_Desarrollo.
177 de 198
Framework Atlas
Normativa
NORMA
CSPMD
Los módulos desarrollados deberán cumplir las reglas de checkstyle y pmd específicas del
framework Atlas.
CODFrecuente
PRACTICA
BUENA
Se recomienda ejecutar frecuentemente las herramientas proporcionadas por el framework
Atlas para validar que se cumplen las normas de codificiación Java (herramientas Checkstyle y
PMD), con el fin de evitar que los incumplimientos de la normativa se vayan acumulando a lo
largo del desarrollo y esto suponga carga adicional de trabajo.
Puede configurarse el entorno de desarrollo Eclipse para que compruebe las normas de
Checkstyle y PMD en caliente, al tiempo que el programador va desarrollando la aplicación.
10.3 GENERACION AUTOMÁTICA DE CODIGO
A partir de la versión 1.2.0 del framework de desarrollo de aplicaciones ATLAS, se incluye una
herramienta de generación automática de código. Esta herramienta permite, a partir de un modelo de
datos, generar código para gestionar las operaciones básicas (alta, baja, modificación y consulta) de ese
modelo de datos de acuerdo a la normativa del framework Atlas en las distintas capas de la aplicación.
La herramienta nos permite seleccionar las tablas de las que queremos generar el código, y a partir de
ellas realiza una ingeniería inversa del modelo de datos y genera el código en la aplicación.
Para el desarrollo de la herramienta se ha tomado como punto de partida el plugin JBoss Hibernate
Tools, y se ha personalizado su configuración para adaptarlo a las necesidades propias de ATLAS.
GENCOD
PRACTICA
BUENA
Se recomienda al inicio del desarrollo utilizar la herramienta de generación automática de
codigo del framework Atlas. El código generado por la herramienta va a reducir el coste/tiempo
de desarrollo del proyecto ya que nos va a generar el código requerido por el framework Atlas
para el acceso a base de datos en las operaciones básicas de alta, baja, modificación y
consulta y en el caso de mantenimiento de catálogos nos va a generar también las pantallas de
usuario que permiten la gestión del catálogo en las operaciones básicas tal y como se ha
indicado.
Atención
El código fuente generado es un punto de partida para el desarrollo. Lo generado se debe evolucionar
178 de 198
Framework Atlas
Normativa
para adaptarlo a las necesidades y requisitos específicos del proyecto.
A continuación se muestran, para cada una de las capas del framework Atlas, los diagramas de clases del
código que se genera. Se ha tomado como ejemplo una entidad de base de datos llamada Expediente.
Para una descripción más detallada de este código y conocer como utilizar la herramienta se debe
consultar el manual ATLAS_MUS_Generador_Codigo que se puede encontrar en la sección “Desarrollos
Atlas->Herramientas” del portal de arquitectura.
179 de 198
Framework Atlas
Normativa
10.3.1 ACCESO A DATOS
En la capa de acceso a datos la herramienta va a generar las clases que la normativa del framework Atlas
determina (Clases de dominio y DAOS) para las operaciones básicas de consulta, alta, baja y modificación.
Además se van a realizar las correspondientes actualizaciones en los ficheros de configuración de Spring
para que estas clases puedan ser usadas desde los servicios de negocio.
Clases generadas para la capa de acceso a datos
class Acceso a Datos
«interface»
dao::BaseDAO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
findAll() : List<T>
countAll() : Long
findAllDistinct() : List<T>
countAllDistinct() : Long
find(PK) : T
find(int, int, AtlasOrder[], AtlasQuery) : List<T>
count(AtlasQuery) : int
exists(PK) : boolean
insert(T) : T
insertOrUpdate(T ) : void
update(T ) : void
delete(PK) : void
delete(T ) : void
findByNamedQuery(String, Map<String, Object>) : List<T>
java.io.Serializable
«interface»
dao::
ExpedienteDAO
T
PK:extends Serializable
HibernateDaoSupport
dao::BaseDAOImpl
-
logger: Log = LogFactory.getL... {readOnly}
persistentClass: Class<T>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#
BaseDAOImpl(Class<T>)
BaseDAOImpl(Class<T>, SessionFactory)
findAll() : List<T >
countAll() : Long
findAllDistinct() : List<T >
countAllDistinct() : Long
find(PK) : T
find(int, int, AtlasOrder[], AtlasQuery) : List<T>
count(AtlasQuery) : int
findInternal(AtlasOrder[], AtlasQuery, boolean) : Criteria
exists(PK) : boolean
insert(T ) : T
insertOrUpdate(T) : void
update(T) : void
delete(PK) : void
delete(T ) : void
findByNamedQuery(String, Map<String, Object>) : List<T>
getLog() : Log
dao::ExpedienteDAOImpl
+
ExpedienteDAOImpl()
expedienteDAO :
ExpedienteDAOImpl
Bean de Spring para
utilizar desde los
servicios de negocio.
180 de 198
domain::Expediente
-
serialVersionUID: long = 1L {readOnly}
idExpediente: Integer
oficina: Oficina
cdExpediente: String
dsExpediente: String
itEstado: String
fcAlta: Date
fcModif: Date
clDsExtendida: Clob
nmCdUadmin: Integer
expeInteresados: Set<ExpeInteresado> = new HashSet<Exp...
expeArchivos: Set<ExpeArchivo> = new HashSet<Exp...
+
+
+
Expediente()
Expediente(Integer)
Expediente(Integer, Oficina, String, String, String, Date, Date, Clob,
Integer, Set<ExpeInteresado>, Set<ExpeArchivo>)
getIdExpediente() : Integer
setIdExpediente(Integer) : void
getPKAsString() : String
getPKFromString(String) : Integer
getOficina() : Oficina
setOficina(Oficina) : void
getCdExpediente() : String
setCdExpediente(String) : void
getT extoListaValores() : String
getDsExpediente() : String
setDsExpediente(String) : void
getItEstado() : String
setItEstado(String) : void
getFcAlta() : Date
setFcAlta(Date) : void
getFcModif() : Date
setFcModif(Date) : void
getClDsExtendida() : Clob
setClDsExtendida(Clob) : void
getNmCdUadmin() : Integer
setNmCdUadmin(Integer) : void
getExpeInteresados() : Set<ExpeInteresado>
setExpeInteresados(Set<ExpeInteresado>) : void
getExpeArchivos() : Set<ExpeArchivo>
setExpeArchivos(Set<ExpeArchivo>) : void
toString() : String
equals(Object) : boolean
hashCode() : int
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Framework Atlas
Normativa
10.3.2 SERVICIOS DE NEGOCIO
En la capa de servicios de negocio la herramienta va a generar las clases que la normativa del framework
Atlas determina (Fachada y Servicios) para las operaciones básicas de consulta, alta, baja y modificación
invocando para su ejecución a los DAOs de la capa de acceso a datos. Además va a realizar las
correspondientes configuraciones para incluir objetos de estos servicios en el contexto de Spring..
Código generado para la capa de servicio de negocio
class Serv icio
«interface»
serv ices::BaseServ ice
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
setDao(D) : void
getDao() : D
findAll() : List<T >
countAll() : Long
findAllDistinct() : List<T >
countAllDistinct() : Long
find(PK) : T
find(int, int, AtlasOrder[], AtlasQuery) : List<T >
count(AtlasQuery) : int
exists(PK) : boolean
insert(T) : T
insertOrUpdate(T) : void
update(T ) : void
delete(PK) : void
delete(T) : void
findByNamedQuery(String, Map<String, Object>) : List<T>
facade::PruebasFacadeImpl
«interface»
serv ices::
ExpedienteServ ice
-expedienteService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
setDao(D) : void
getDao() : D
findAll() : List<T >
countAll() : Long
findAllDistinct() : List<T>
countAllDistinct() : Long
find(PK) : T
find(int, int, AtlasOrder[], AtlasQuery) : List<T >
count(AtlasQuery) : int
exists(PK) : boolean
insert(T ) : T
insertOrUpdate(T ) : void
update(T) : void
delete(PK) : void
delete(T) : void
findByNamedQuery(String, Map<String, Object>) : List<T >
+
+
setExpedienteService(ExpedienteService) : void
findExpediente(int, int, AtlasOrder[], AtlasQuery) :
List<Expediente>
findExpediente(Integer) : Expediente
countExpediente(AtlasQuery) : int
insertExpediente(Expediente) : void
updateExpediente(Expediente) : void
insertOrUpdateExpediente(Expediente) : void
deleteExpediente(Expediente) : void
deleteExpediente(Integer) : void
«interface»
facade::PruebasFacade
+
serv ices::BaseServ iceImpl
logger: Log = LogFactory.getL... {readOnly}
dao: D
expedienteService: ExpedienteService
+
+
+
+
+
+
+
T
PK:extends Serializable
D:extends BaseDAO<T, PK>
-
-
expedienteDAO :
ExpedienteDAOImpl
expediente :
Expediente
+
+
+
+
+
+
+
findExpediente(int, int, AtlasOrder[], AtlasQuery) :
List<Expediente>
findExpediente(Integer) : Expediente
countExpediente(AtlasQuery) : int
insertExpediente(Expediente) : void
updateExpediente(Expediente) : void
insertOrUpdateExpediente(Expediente) : void
deleteExpediente(Expediente) : void
deleteExpediente(Integer) : void
serv ices::
ExpedienteServ iceImpl
expedienteServ ice :
ExpedienteServ iceImpl
pruebasFacade :
PruebasFacadeImpl
Bean de Spring para
ser usado desde los
beans de respaldo de
JSF
181 de 198
Framework Atlas
Normativa
10.3.3 PRESENTACION
En la capa de presentación se generan para cada una de las entidades/tablas unas pantallas que nos
permitan realizar el mantenimiento básico de dicha tabla. La generación de la parte de presentación está
pensada como una solución para generar el código asociado al mantenimiento de cátalogos que
tipicamente podemos encontrar en las aplicaciones.
A continuación se muestra el código generado en la capa de presentación:
Código generado: Presentación
class Presentacion
listaExpediente.xhtml
formularioExpediente.xhtml
expedienteBean :
ExpedienteBean
expedienteBean :
ExpedienteBean
Managed Bean para
ser usado desde las
páginas JSF
j sf::ExpedienteBean
-
serialVersionUID: long = 1L {readOnly}
facade: PruebasFacade
orderAndFilter: OrderAndFilterBean = null
entidad: Expediente = null
listaValoresOficina: ListaValores
textoOficina: String
oficinaFilter: String
cdExpedienteFilter: String
dsExpedienteFilter: String
itEstadoFilter: String
fcAltaFilter: Date
fcModifFilter: Date
scroller: UIDataScroller = new UIDataScroller()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ExpedienteBean()
getEntidad() : Expediente
setEntidad(Expediente) : void
getFacade() : PruebasFacade
setFacade(PruebasFacade) : void
getTimeZone() : TimeZone
getOrderAndFilter() : OrderAndFilterBean
setOrderAndFilter(OrderAndFilterBean) : void
obtener(int, int, Object, Object) : List<Expediente>
obtenerTotal(Object) : int
cargar() : String
cargar(ActionEvent) : void
eliminar() : String
eliminar(ActionEvent) : void
confirmarEliminar() : String
confirmarEliminar(AjaxBehaviorEvent) : void
guardar() : String
nuevo() : String
volver() : String
getListaValoresOficina() : ListaValores
setListaValoresOficina(ListaValores) : void
setTextoOficina(String) : void
getTextoOficina() : String
obtenerListaOficina(int, int, Object, Object) : List<AtlasHashMap>
obtenerTotalOficina(Object) : int
getOficinaFilter() : String
setOficinaFilter(String) : void
getCdExpedienteFilter() : String
setCdExpedienteFilter(String) : void
getDsExpedienteFilter() : String
setDsExpedienteFilter(String) : void
getItEstadoFilter() : String
setItEstadoFilter(String) : void
getFcAltaFilter() : Date
setFcAltaFilter(Date) : void
getFcModifFilter() : Date
setFcModifFilter(Date) : void
getScroller() : UIDataScroller
setScroller(UIDataScroller) : void
filtrar() : String
setIdOficina(String) : void
getRequiredMessage() : String
«interface»
facade::PruebasFacade
+
+
-facade +
+
+
+
+
+
-entidad
182 de 198
countExpediente(AtlasQuery) : int
insertExpediente(Expediente) : void
updateExpediente(Expediente) : void
findExpediente(int, int, AtlasOrder[], AtlasQuery) :
List<Expediente>
findExpediente(Integer) : Expediente
insertOrUpdateExpediente(Expediente) : void
deleteExpediente(Expediente) : void
deleteExpediente(Integer) : void
java.io.Serializable
domain::Expediente
Framework Atlas
Normativa
A continuación se muestran ejemplos de pantallas generadas para el mantenimiento de la entidad
Expediente.
Ejemplo de página xhtml generada
Listado: listaExpediente.xhtml
Desde esta pantalla nos permite realizar las siguientes operaciones:
·
Búsqueda basada en filtros
·
Nuevo elemento: Accede a la pantalla de alta
·
Eliminación
·
Edición: Accede a la pantalla de edición
Características de esta pantalla:
·
Filtros:
o
Para cada campo de la tabla de tipo Textual se genera un <inputText> para buscar en ese
campo.
o
En el caso de que un campo sea una foreign key de una tabla se genera un <inputText>
para buscar en el primer campo de tipo texto de la tabla foránea.
·
Tabla de resultados:
o
Ordenación por columnas
o
Paginación
183 de 198
Framework Atlas
Normativa
Ejemplo de página xhtml generada
Página de alta y edición: formularioExpediente.xhtml
Características de esta pantalla:
·
Para los campos que son foreign key de otra tabla se genera un <inputText> asociado a una lista
de valores.
·
Para los campos de tipo Date se genera un campo de tipo Calendario
·
Resto de campos se genera un <inputText> de tamaño fijo
·
Cada campo lleva asociado un enlace a una ayuda de contexto
·
Los campos generados de tipo <inputText> cuyo valor es obligatorio (en la tabla de base de datos
tienen la propiedad NOT NULL) se marcan en amarillo, y si no se rellenan se muestra un mensaje
de error indicándolo.
184 de 198
Framework Atlas
Normativa
11
PRUEBAS
El desarrollo de software requiere e implica la construcción de aplicaciones de forma robusta, extensible y
escalable. Conseguir dichos objetivos requiere la aplicación de una metodología de desarrollo que
incluya la realización de pruebas de software precisas.
El “objetivo de las pruebas” de software es “asegurar que el producto final cumple todas las
funcionalidades requeridas por los usuarios”. Para conseguir dicho objetivo, los encargados de realizar las
pruebas tendrán que revisar el producto final y concluir si los requisitos iniciales son completamente
satisfechos. La ejecución de pruebas es tan importante que se debe hacer durante todo el tiempo y a
lo largo del ciclo de vida de desarrollo del software. Mediante las pruebas de software es posible
demostrar formalmente que las especificaciones funcionales y técnicas se cumplen. Un software probado
contendrá menos errores y será más seguro. Por otro lado, la demora en la corrección de errores software
hace que sea más costosa su detección y eliminación. Si un error es detectado en el mismo momento en el
cual el desarrollador hace un cambio, será probable que pueda arreglarlo en ese instante. Por el contrario
si un error no es detectado hasta después de la entrega parcial o final el coste de su detección se dispara,
además de la consiguiente pérdida de confianza generada. Por último comentar que la realización de
pruebas permite poder refactorizar el código con la seguridad de que el comportamiento seguirá siendo
correcto. La refactorización ayuda a resaltar o recuperar la claridad de un diseño que se ha ido
complicando a causa de modificaciones o implementaciones posteriores.
11.1 TIPOS DE PRUEBAS
Los tipos de pruebas a desarrollar en el momento de probar el software pueden ser categorizadas de
diferente forma:
·
Pruebas unitarias: Las pruebas unitarias ejercitan el funcionamiento de una unidad de código,
normalmente una clase aislada del resto de la aplicación. Su objetivo es comprobar que su
estructura es correcta y que se ajusta a la funcionalidad establecida previamente y aprobada en la
fase de análisis.
Es muy importante incorporar la implementación de pruebas unitarias a la metodología de
desarrollo, de modo que las pruebas unitarias se desarrollen a la vez que se implementa el
código, probando cada parte del código que se desarrolla (test-driven development, o desarrollo
guiado por las pruebas).
185 de 198
Framework Atlas
Normativa
TESTUnitarios
Todos los bloques funcionales de la aplicación deberán contener Tests que realicen las
pruebas unitarias de dicho bloque funcional.
Para implementar las pruebas unitarias se utilizará como herramienta principal JUnit (los
arquetipos ya vienen preparados para trabajar con esta herramienta).
Se podrán utilizar objetos mock como los pertenecientes a las librerías JMock, Spring
NORMA
Mock, EasyMock y PowerMock.
Se podrán utilizar herramientas a modo de extensión de JUnit como pueda ser DBUnit que
mejoren y faciliten el proceso de pruebas unitarias.
Las clases de testeo se deben incluir en la carpeta src/test/java. Desde de esta carpeta se
crearan con la misma estructura de paquetes que se ha definido en el proyecto.
Los recursos necesarios para ejecutar las pruebas (ficheros de configuración, etc) se
incluirán en la carpeta src/test/resources.
Esta batería de pruebas nunca se deberá incluir en el proyecto final que se despliegue en el
entorno de producción (esto será controlado por maven en empaquetación de la
aplicación).
·
Pruebas de integración: Las pruebas integrales o pruebas de integración son aquellas que se
realizan en el ámbito del desarrollo de software una vez que se han aprobado las pruebas
unitarias. Únicamente se refieren a la prueba o pruebas de todos los elementos unitarios que
componen un proceso, hecha en conjunto, de una sola vez.
Estas pruebas permiten comprobar que la unión de partes de software funcionan juntos y de forma
correcta.
186 de 198
Framework Atlas
Normativa
TESTIntegracion
Para realizar los test de integración se recomienda la utilización del paquete
org.springframework.test “spring-mock.jar” que permite realizar pruebas de integración
mediante el contenedor Spring.
NORMA
También se permite el uso de las librerías JMock, EasyMock y PowerMock
Las clases de testeo se deben incluir en la carpeta src/test/java. Desde de esta carpeta se
crearan con la misma estructura de paquetes que se ha definido en el proyecto.
Los recursos necesarios para ejecutar las pruebas (ficheros de configuración, etc) se
incluirán en la carpeta src/test/resources.
Esta batería de pruebas nunca se deberá incluir en el proyecto final que se despliegue en el
entorno de producción (esto será controlado por maven en empaquetación de la aplicación).
·
Pruebas funcionales (aceptación): Las pruebas funcionales y de aceptación permiten a los
usuarios finales comprobar que toda la funcionalidad de la aplicación está implementada. Puede
involucrar procesos de pruebas automáticas y parte manual aunque esto último debe limitarse al
mínimo.
TESTAceptacion
Para automatizar pruebas de aceptación de módulos web se utilizará la herramienta
Selenium.
NORMA
Cuando las pruebas a realizar sean sobre servicios web, se utilizará la herramienta SoapUI.
Los tests de Selenium deben ir incluidos en un módulo del proyecto aparte llamado “test”,
que se crea al generar el proyecto partiendo del arquetipo.
Las clases de testeo se deben incluir en la carpeta src/test/java del módulo test.
Los recursos necesarios para ejecutar las pruebas con Selenium (ficheros de configuración,
etc) se incluirán en la carpeta src/test/resources del módulo test.
·
Pruebas de servicios web: Las pruebas de los servicios web permiten a los clientes finales de los
servicios web comprobar el correcto funcionamiento de los mismos además de poder automatizarla
187 de 198
Framework Atlas
Normativa
y repetir dichas pruebas en cualquier momento. Estas pruebas se realizan utilizando la herramienta
SoapUI.
TESTServiciosWeb
Se implementarán pruebas en los módulos de tipo webservice para cubrir los distintos
NORMA
métodos expuestos en las interfaces de los distintos servicios web del módulo.
Para implementar las pruebas de servicios web se utilizará la herramienta SoapUI.
Los tests de SoapUI deben ir incluidos en el submódulo del proyecto llamado “test”, que se
crea al generar el proyecto partiendo del arquetipo.
Los tests se deben incluir en la carpeta src/test/soapui del módulo test.
·
Pruebas de carga y stress: Las pruebas de carga y stress evalúan el rendimiento del sistema en
base a los requisitos. Permite verificar el comportamiento del sistema en situaciones extremas,
tanto en carga como en tiempo, donde los usuarios y peticiones se producen de forma
concurrente.
TESTRendimiento
Se implementarán pruebas de carga y estrés para las funcionalidades de la aplicación en
NORMA
las que el rendimiento sea un factor a tener en cuenta.
Para implementar las pruebas de carga y estrés se utilizará JMeter.
Los tests de JMeter deben ir incluidos en un módulo del proyecto aparte llamado “test”, que
se crea al generar el proyecto partiendo del arquetipo.
Los tests se deben incluir en la carpeta src/test/jmeter del módulo test.
·
Pruebas de usabilidad: Las pruebas de usabilidad permiten comprobar que la aplicación no solo
cumple funcionalmente su cometido, sino que además, es fácil e intuitivo su uso.
·
Revisiones de código estático: Una vía de detección de muchos errores y de mejora de los
diseños es la realización de revisiones de código. Las revisiones de código se realizan por el
propio desarrollador y por otros desarrolladores. Es altamente recomendable realizar revisiones de
código periódicas, ya que mejoran la calidad del software tanto en diseño como en robustez. Este
tipo de revisiones ya se han indicado en el apartado Validación de codificación Java.
188 de 198
Framework Atlas
Normativa
NORMA
TESTAutomatizacion
NORMA
A continuación se definen algunas normas generales para la ejecución de pruebas:
TESTCobertura
Se empleará Maven como herramienta para la ejecución automática de las pruebas y los
informes de resultados de las mismas.
La cobertura del código debe incluir las ramas principales y de más importancia en la
aplicación.
189 de 198
Framework Atlas
Normativa
11.2 PLAN DE PRUEBAS
Un plan de pruebas debe ser interpretado como la piedra angular y en consecuencia el principal factor
crítico de éxito para la puesta en práctica de un proceso de pruebas que permita entregar un software de
calidad ya que resumirá, entre otras cosas, las actividades de prueba que se deberán realizar.
De tal forma, se puede definir el plan de pruebas como un documento que describe el alcance, enfoque,
recursos y calendario de las actividades de prueba. Además identificará elementos a evaluar,
características, tareas, responsabilidades y prevendrá de riesgos que quizás requieran un plan de
contingencia. Identifica ítems de prueba, características a ser probadas, tareas de prueba, quien realizará
cada tarea y riesgos que quizás requieran un plan de contingencia.
Además, los planes de pruebas son especialmente útiles al tratarse de documentos sencillos de revisar, lo
que confiere la posibilidad a individuos que pertenecen a roles distintos (equipo de ingenieros,
responsables de proyecto, etc.) poder inspeccionarlo y adaptarlo a sus necesidades concretas.
TESTPlanPruebas
Como parte de los entregables de los proyectos será necesario entregar los planes de
pruebas, los resultados de los mismos y un informe de evaluación de dichos resultados.
El plan de pruebas entregado por el proveedor tendrá que incorporar (como mínimo) los
siguientes elementos
·
Identificador del plan de pruebas: El identificador será de alguna forma
mnemónica que permita relacionarlo con su alcance, por ejemplo: PP-Global (plan
de pruebas global), PP-Aceptacion (plan de pruebas para pruebas de aceptación),
NORMA
etc.
·
Versión y la fecha del plan de pruebas.
·
Alcance del plan de pruebas: Se deberá especificar los requisitos que se van a
probar con este plan. Por otra parte se deberán indicar igualmente aquellos
requisitos excluidos justificando los motivos por los cuales no se van a probar.
·
Configuración necesaria
·
Para cada uno de los siguientes tipos de pruebas incluir un apartado donde se
especifiquen los casos de prueba, el instrumento o herramienta usada, donde
pueden ser encontrados, cómo serán ejecutados y los datos que serán usados.
·
Pruebas unitarias
·
Pruebas de integración
·
Pruebas de aceptación
·
Pruebas de carga y estrés
190 de 198
Framework Atlas
Normativa
11.3 DOCUMENTACION DEL CODIGO
La documentación del código debe explicar claramente que función realiza dicho código y debe exponer
toda funcionalidad interna que afecte a su comportamiento externo.
Además debe incluir información que permita identificar el autor del código (el proveedor) para permitir una
rápida resolución del problema. Por otra parte, es necesario que se incluya información sobre la versión en
la que se incluyeron nuevos métodos o la etiqueta deprecated si el método está obsoleto.
JAVADOC
NORMA
Todas las clases Java de las aplicaciones deberán incluir tanto en sus métodos como en sus
propiedades las correspondientes etiquetas de Javadoc que permitan generar la documentación
correspondiente.
Asimismo, todas las clases java deben incluir una cabecera en la que se muestre una descripción
de la clase, y en la que se incluya la etiqueta @author indicando el proveedor que realiza el
desarrollo.
El porcentaje de javadoc que se debe incluir es del 100%.
A continuación se muestra un ejemplo de clase Java con la documentación completa:
package ejpl.comunes.general;
import java.util.Properties;
/**
* Clase de ejemplo correctamente documentada con javadoc
* @author ICM
*/
public class EjemploJavaDoc {
/** identificador de serialización */
private static final long serialVersionUID = 30460628734587345L;
/** Ejemplo de variable */
public static final String CONSTANTE = "prueba";
/**
* Ejemplo de método documentado
* @return un objeto de tipo {@link String}
*/
public String getValor() {
return CONSTANTE;
}
}
191 de 198
Framework Atlas
Normativa
12
ENTREGA
El proveedor desarrollará los distintos módulos en sus instalaciones y posteriormente realizará la entrega al
Responsable de Proyecto para que solicite a la Unidad de de Paso a Producción el despliegue de la
misma en el entorno de desarrollo. La Unidad de Paso a Producción desempeña actualmente las tareas de
despliegue en el entorno de desarrollo durante la fase de construcción y hasta la puesta en producción de
la aplicación.
La Unidad de Paso a Producción dispone de un servidor SFTP para que los proveedores puedan realizar
las entregas.
La entrega del proyecto de un proveedor externo al responsable de proyecto deberá efectuarse mediante
alguno de los siguientes mecanismos:
·
Entrega de un CD/DVD al jefe de proyecto
·
Entrega en el directorio del proveedor en el SFTP destinado a tal efecto
En cada entrega el proveedor deberá cumplimentar una ficha de instalación (disponible en la web) que
deberá enviar al responsable de proyecto para que la revise antes de solicitar la instalación.
La Unidad de Paso a Producción se encargará de la compilación y despliegue de los distintos módulos
entregados sin la asistencia del proveedor, por lo tanto la entrega deberá tener la estructura de directorios
exigida y todo el código fuente, librerias, etc necesarios para la compilación del proyecto. Pudiendo
desestimarse la instalación si no se cumple lo anterior.
PRACTICA
BUENA
ENTREGAParcial
A lo largo del ciclo de vida del desarrollo del proyecto es recomendable realizar al menos dos
entregas intermedias a ICM, al 30% y 70% del desarrollo, no realizando una única entrega final
con todo el proyecto sólo cuando esté finalizado.
La Unidad de Paso a Producción emitirá un resumen de la realización de la instalación al jefe de proyecto.
Tras la primera instalación de un proyecto la Unidad de Paso a Producción creará el repositorio de
subversion para el control de versiones de este proyecto.
A partir de este momento las solicitudes a la Unidad de Paso a Producción pueden hacerse bien con una
nueva entrega en el servidor FTP o bien creando subiendo la entrega a subversión tal y como se indica en
192 de 198
Framework Atlas
Normativa
el siguiente manual:
NORMA
http://www.madrid.org/arquitecturasw/images/documentacion/portal/actual/Guia_Uso_Subversion.pdf
ENTREGABUILD
Es obligatorio que la aplicación entregada compile correctamente sin errores.
NORMA
NORMA
ENTREGATARGET
13
La entrega sólo debe contener los ficheros fuente del proyecto, no se incluirá el directorio “target”
generado por Maven. Dentro de la entrega no se incluirá ninguna librería “jar” ya que éstas se
descargarán automáticamente del repositorio artifactory.
ENTREGALIB
Las aplicaciones no podrán utilizar librerías externas que no estén incluidas en el repositorio
artifactory de ICM, a no ser que sean autorizadas por ICM.
ENLACES RELACIONADOS
Producto
URL
Portal para el desarrollo http://gestiona.madrid.org/arquitecturasw
de aplicaciones
Artifactory de Atlas
http://gestiona.madrid.org/artifactory
193 de 198
Framework Atlas
Normativa
A1.1
NORMAS
ENTORNO .................................................................................................................................................................... 19
ENTORNOEJECUCION ............................................................................................................................................. 19
ARQUETIPOS .............................................................................................................................................................. 21
NOMARCHIVO ............................................................................................................................................................ 22
NOMPAQUETES ......................................................................................................................................................... 22
VERSIONADO .............................................................................................................................................................. 22
IMPLWEB ..................................................................................................................................................................... 23
LIBCOMUN .................................................................................................................................................................. 24
IMPLLIB ....................................................................................................................................................................... 24
IMPLWS ........................................................................................................................................................................ 25
WSLIBCLIENTE .......................................................................................................................................................... 25
IMPLBATCH ................................................................................................................................................................ 26
REFLEXION ................................................................................................................................................................. 27
GARBAGE .................................................................................................................................................................... 27
MULTIHILO ................................................................................................................................................................. 27
CLASESIGUALES ....................................................................................................................................................... 27
JSFCOMPONENTES ................................................................................................................................................... 29
JSFXHTML ................................................................................................................................................................... 30
JSFPOB .......................................................................................................................................................................... 30
JSFNEGOCIO ............................................................................................................................................................... 33
JSFVALIDACION ........................................................................................................................................................ 38
JSFCUSTOMVALIDATOR ........................................................................................................................................ 39
JSFCUSTOMCONVERSOR ....................................................................................................................................... 39
JSFINTERNALIZACION............................................................................................................................................ 40
JSFLAYOUT ................................................................................................................................................................. 44
JSFPANEL .................................................................................................................................................................... 45
JSFCUSTOMMENU .................................................................................................................................................... 46
JSFJAVASCRIPT ......................................................................................................................................................... 46
JSFJQUERY.................................................................................................................................................................. 46
JSFACCESIBILIDAD .................................................................................................................................................. 48
JSFIMAGENES ............................................................................................................................................................ 48
JSFCSS ........................................................................................................................................................................... 49
JSFIFRAMES................................................................................................................................................................ 49
JSFAJAX ....................................................................................................................................................................... 50
JSFAJAXINTERAC ..................................................................................................................................................... 50
JSFMBEANSIMPL....................................................................................................................................................... 54
JSFANOTACION ......................................................................................................................................................... 56
194 de 198
Framework Atlas
Normativa
JSFMBATRIBUTOS .................................................................................................................................................... 56
JSFFACADE ................................................................................................................................................................. 57
JSFEXCEPTION .......................................................................................................................................................... 58
JSFNAVEGACION ...................................................................................................................................................... 59
JSFFACESCONFIGXML ............................................................................................................................................ 62
JSFREQUEST ............................................................................................................................................................... 63
JSFNAVDES.................................................................................................................................................................. 65
JSFCONFADICIONAL................................................................................................................................................ 67
JSFWEBXML ............................................................................................................................................................... 67
JSFSESION ................................................................................................................................................................... 69
JSFHTTPSESSION ...................................................................................................................................................... 69
JSFTIEMPOSESION ................................................................................................................................................... 69
JSFUSOSESION ........................................................................................................................................................... 69
JSFCREACIONSESION .............................................................................................................................................. 70
SNFACADE ................................................................................................................................................................... 72
SNFACADEIMPL......................................................................................................................................................... 73
SNDOMINIO ................................................................................................................................................................. 74
SNSERVICEIMPL ....................................................................................................................................................... 76
SNANOTACION ........................................................................................................................................................... 76
SNMVC .......................................................................................................................................................................... 77
SNSPRING .................................................................................................................................................................... 81
SNSPRINGLIB .............................................................................................................................................................. 81
SNDEPENDENCIAS .................................................................................................................................................... 82
SNAMBITOS ................................................................................................................................................................. 83
SNTHROWSEXCEPTION .......................................................................................................................................... 84
SNCUSTOMEXCEPTION .......................................................................................................................................... 84
SNNEGOCIOEXCEPTION ......................................................................................................................................... 85
SNSYSTEMEXCEPTION............................................................................................................................................ 86
SNDAOEXCEPTION ................................................................................................................................................... 86
SNTRANSACTIONANNOTATED ............................................................................................................................. 91
SNTRANSACTIONDEFAULT ................................................................................................................................... 91
SNTRANSACTIONROLLBACK ............................................................................................................................... 92
SNFICHEROSTEMPORALES ................................................................................................................................... 94
ADHIBERNATE ........................................................................................................................................................... 96
DAODATASOURCE .................................................................................................................................................... 97
DAOSESSION ............................................................................................................................................................... 97
DAOFLUSHING ........................................................................................................................................................... 97
DAODEPENDENCIAS .............................................................................................................................................. 101
ADENTITYIMPL ....................................................................................................................................................... 102
ADRENDIMIENTO ................................................................................................................................................... 102
195 de 198
Framework Atlas
Normativa
ADEQUALSHASHCODE .......................................................................................................................................... 108
ADMAPEOTABLA .................................................................................................................................................... 109
ADIDENTIFICADOR ................................................................................................................................................ 109
ADRELACIONES....................................................................................................................................................... 110
ADDINAMICOS ......................................................................................................................................................... 110
ADLOBANOT ............................................................................................................................................................. 110
ADHIBERNATEDAOIMPL ...................................................................................................................................... 113
ADDAOANOTACION ............................................................................................................................................... 113
ADDAONOMENCLATURA ..................................................................................................................................... 114
ADDAOHIBERNATETEMPLATE .......................................................................................................................... 114
ADCATALOGOS ....................................................................................................................................................... 121
ADREMOTO ............................................................................................................................................................... 121
ADSQL ......................................................................................................................................................................... 122
ADSQLUSO ................................................................................................................................................................. 122
ADNAMEDPARAMETER ........................................................................................................................................ 123
DAOEXCEPCIONES ................................................................................................................................................. 124
ADTRANSACCION ................................................................................................................................................... 124
ADROLLBACK .......................................................................................................................................................... 125
ADSTOREDPROC ..................................................................................................................................................... 126
ADCACHE2NIVEL .................................................................................................................................................... 131
DAOCACHEDISTRIBUIDA ..................................................................................................................................... 132
ADRENDIMIENTO ................................................................................................................................................... 132
CONFENTORNO ....................................................................................................................................................... 134
CONFPARTICULAR ................................................................................................................................................. 134
CONFPARTICULARLIB .......................................................................................................................................... 135
CONFENTORNOLIB ................................................................................................................................................ 135
CONFNOMENCLATURA ........................................................................................................................................ 136
CONFSEG ................................................................................................................................................................... 136
SBAUTENAUTO ........................................................................................................................................................ 140
SBAUTOPERFILES ................................................................................................................................................... 140
SBENS .......................................................................................................................................................................... 142
SBTRAZAS.................................................................................................................................................................. 144
SBTRAZASSEG .......................................................................................................................................................... 145
SBAUDIT ..................................................................................................................................................................... 146
SIPLAN ........................................................................................................................................................................ 149
SICERT ........................................................................................................................................................................ 150
SIBI............................................................................................................................................................................... 152
INTWS ......................................................................................................................................................................... 153
INTNOMCLIENT....................................................................................................................................................... 153
SIBPM .......................................................................................................................................................................... 155
196 de 198
Framework Atlas
Normativa
SOLLIB ........................................................................................................................................................................ 155
SOLRPT ....................................................................................................................................................................... 156
SOLRPTCONEX ........................................................................................................................................................ 156
SOLRPTMODULO .................................................................................................................................................... 157
SOLRPTCONF ........................................................................................................................................................... 157
SOLCOMPOSITOR ................................................................................................................................................... 158
SOLEXCEL ................................................................................................................................................................. 160
SOLPDF ....................................................................................................................................................................... 161
SOLGRAFICOS .......................................................................................................................................................... 162
SOLMULTIMEDIA ................................................................................................................................................... 163
SOLACCESOLOCAL ................................................................................................................................................ 164
SOLXML ..................................................................................................................................................................... 166
SOLCORREO ............................................................................................................................................................. 168
WSSECURITY ............................................................................................................................................................ 174
VALEXCLUDE ........................................................................................................................................................... 176
CSPMD ........................................................................................................................................................................ 178
TESTINTEGRACION ............................................................................................................................................... 187
TESTACEPTACION .................................................................................................................................................. 187
TESTSERVICIOSWEB ............................................................................................................................................. 188
TESTRENDIMIENTO ............................................................................................................................................... 188
TESTAUTOMATIZACION ...................................................................................................................................... 189
TESTCOBERTURA ................................................................................................................................................... 189
TESTPLANPRUEBAS ............................................................................................................................................... 190
JAVADOC ................................................................................................................................................................... 191
ENTREGABUILD ...................................................................................................................................................... 193
ENTREGATARGET .................................................................................................................................................. 193
ENTREGALIB ............................................................................................................................................................ 193
197 de 198
Framework Atlas
Normativa
A1.2 BUENAS PRACTICAS
JSFMANAGEDBEAN .................................................................................................................................................. 32
JSFGET.......................................................................................................................................................................... 32
JSFTAMANO ................................................................................................................................................................ 33
JSFEL ............................................................................................................................................................................. 33
JSFACCIONES ............................................................................................................................................................. 35
JSFMESSAGES ............................................................................................................................................................ 38
JSFACCESOMESSAGES ............................................................................................................................................ 41
JSFAJAXLIMITE......................................................................................................................................................... 51
JSFAYUDA.................................................................................................................................................................... 53
JSFMBUNICO .............................................................................................................................................................. 56
JSFSTOREERROR ...................................................................................................................................................... 59
JSFSAVESTATE .......................................................................................................................................................... 64
JSFATLASFACESUTILS ............................................................................................................................................ 70
SNFACADEWS ............................................................................................................................................................. 73
ADBASESERVICE ....................................................................................................................................................... 79
SNAGRUPACION ........................................................................................................................................................ 83
SNEXCCOMUNES ....................................................................................................................................................... 85
SNGENERICTRANSACTION .................................................................................................................................... 91
SNNOMFICHEROTEMPORAL ................................................................................................................................ 94
ADBASEDAO .............................................................................................................................................................. 117
ADHQL ........................................................................................................................................................................ 121
SOLCOMPOSITOR ................................................................................................................................................... 158
SOLGRAFICOSGRANDES ...................................................................................................................................... 162
VALFRECUENTE ...................................................................................................................................................... 175
CODFRECUENTE ..................................................................................................................................................... 178
GENCOD ..................................................................................................................................................................... 178
ENTREGAPARCIAL ................................................................................................................................................. 192
198 de 198
Descargar