Sunteți pe pagina 1din 139

UNIVERSIDAD DE MLAGA

ESCUELA TCNICA SUPERIOR DE INGENIERA INFORMTICA

INGENIERO TCNICO EN INFORMTICA DE GESTIN

Arquitectura J2EE para el desarrollo gil de aplicaciones webs

Realizado por Javier Cisneros Gonzlez

Dirigido por Francisco Rus Mansilla Francisco Romn Villatoro Machuca

Departamento Lenguaje y Ciencias de la Computacin

UNIVERSIDAD DE MLAGA

MLAGA, Diciembre 2010 1

UNIVERSIDAD DE MLAGA ESCUELA TCNICA SUPERIOR DE INGENIERA INFORMTICA

INGENIERO TCNICO EN INFORMTICA DE GESTIN Reunido el tribunal examinador en el da de la fecha, constituido por: Presidente/a D/D. ________________________________________________________________ Secretario/a D/D. ________________________________________________________________ Vocal D/D. _____________________________________________________________________ para juzgar el proyecto Fin de Carrera titulado: Arquitectura J2EE para el desarrollo gil de aplicaciones webs realizado por D. Javier Cisneros Gonzlez tutorizado por D. Francisco Rus Mansilla y D Francisco Romn Villatoro Machuca, y, en su caso, dirigido acadmicamente por D/D.___________________________________________________________________________ ________________________________________________________________________________ ACORD POR ______________________________________ OTORGAR LA CALIFICACIN DE _____________________________________________________________________________ Y PARA QUE CONSTE, SE EXTIENDE FIRMADA POR LOS COMPARECIENTES DEL TRIBUNAL, LA PRESENTE DILIGENCIA.

Mlaga a ____ de______________ del 2011

Agradecimientos

ndice
Pgina 1. Introduccin 1.1. Descripcin del proyecto 1.2. Antecedentes 1.3. Objetivos 1.4. Fases de trabajo 1.5. Estructura de la memoria 1.6. Requisitos 2. Arquitectura en JAVA con Maven 2.1. JAVA 2.1.1. Framework 2.1.2. POJO 2.1.3. Bean 2.2. Patrn de diseo 2.2.1. Patrn MVC 2.2.2. Patrones de diseo J2EE 2.2.3. Patrn de inversin de control 2.2.4. Patrn de inyeccin de dependencias 2.3. Maven 3. Frameworks necesarios en la arquitectura 3.1. ORM 3.1.1. Hibernate 3.2. JSF 3.2.1. Myfaces 3.2.2. Tomahawk 3.2.3. Primefaces 3.3. Spring Security 3.4. Herramientas de test 3.4.1. JUnit 3.4.2. JMock 3.4.3. JMeter 3.5. Spring Framework 3.6. Log4j 4. Definicin de la arquitectura 4.1. Capa Model 4.2. Capa Core 4.2.1. Capa DAO 4.2.2. Capa Services 4.3. Capa Web 4.3.1. Capa Vista 4.3.2. Capa Action 4.4. Convenio de nombres 5. Creacin del arquetipo 5.1. Infraestructura de desarrollo 5.1.1. Google Code 5.2. Definiendo el proyecto 7 7 7 8 8 8 9 11 11 12 12 12 12 14 14 17 18 18 29 29 29 32 34 36 37 38 42 42 43 44 46 50 53 55 56 58 59 61 61 63 68 71 71 71 74 5

5.3. Instalacin de los frameworks y herramientas en la arquitectura 5.3.1. JAVA 5.3.2. Maven 5.3.3. Frameworks JAVA 5.3.3.1. Myfaces 5.3.3.2. Primefaces 5.3.3.3. Tomahawk 5.3.4. Spring Framework 5.3.5. Hibernate 5.3.6. Spring Security 5.3.7. Log4j 5.3.8. Framework para los test 5.4. Generacin del arquetipo 6. Trabajando con la arquitectura 6.1. Preparacin y descarga 6.2. Utilizacin de la arquitectura 6.2.1. Model 6.2.2. Core 6.2.3. Web 7. Herramientas para el uso de la arquitectura 7.1. IDE 7.1.1. Eclipse 7.1.2. Netbeans 7.1.3. Intellij IDEA 7.2. Base de datos 7.2.1. MySQL 7.2.2. Postgresql 7.3. Servidores de aplicaciones 7.3.1. Apache Tomcat 7.3.2. JBoss AS 7.3.3. Jetty 7.4. SVN 7.5. Instalacin de las herramientas 7.5.1. Bases de datos 7.5.1.1. MySQL 7.5.1.2. PostgreSql 7.5.2. IDE 7.5.2.1. Eclipse 7.5.2.2. Netbeans 7.5.2.3. Intellij IDEA 7.5.3. Servidor de aplicaciones 7.5.3.1. Apache Tomcat 7.5.3.2. Jboss 7.5.3.3. Jetty 7.5.4. SVN 8. Conclusiones 9. Bibliografa y enlaces 9.1. ndice de figuras 9.2. ndice de tablas

80 84 85 85 85 86 87 88 89 92 94 95 96 97 97 98 99 102 108 117 117 117 118 120 121 122 122 123 123 124 126 127 128 128 128 128 129 129 129 130 130 130 131 131 132 134 135 136 136 6

1. Introduccin
JAVA es el lenguaje de programacin ms utilizado y ms famoso del mundo. Sin duda ha contribuido a su xito ese desplazamiento al sector de las aplicaciones web que lleva sufriendo desde la llegada de Internet. La forma de resolver JAVA el paradigma web fue mediante sus servlets y jsp. Posteriormente fue estandarizando en los llamados frameworks. Los frameworks revolucionaron las aplicaciones web consiguiendo que el trabajo fuera ms gil. Contienen una gran cantidad de funcionalidad y estn mantenidos por una comunidad que intenta optimizar el cdigo en la medida de lo posible. Uno de estos frameworks que deben de ser el referente en los prximos aos es Java Server Faces 2, Despus del xito cosechado por la primera versin y gracias a los esfuerzos de la comunidad Apache, JSF debe de ser el framework que ms utilizaran los programadores de aplicaciones web. Hay varias implementaciones de JSF 2 entre las que destaca Myfaces 2.0. Myfaces tiene muchos componentes que hacen que no se tenga que estar programando una y otra vez algunas partes de las pginas webs. Se integra con herramientas muy potentes como Spring y tecnologas como AJAX. Otro framework que tenemos que hacer mencin especial es Hibernate. Un ORM (Object Relational Modeling) que simplifica la gestin con la base de datos hacindola tan sencilla que hacen olvidar que exista una base de datos relacional y hace creer de que se trabaje directamente con objetos de un lenguaje orientado a objetos Pero si todo funciona tan bien en JAVA cual es el problema? El problema es que JAVA se hace cada vez ms complejo. Sus proyectos son ms difciles de mantener y hace falta cada vez un personal ms cualificado para gestionar los proyectos. Los proyectos conllevan un coste muy grande a la hora de iniciarse y de documentarse. An ms cuando hay incidencias en las APIs que se estn utilizando y hay que actualizarlas. Los clientes exigen las ltimas tecnologas y los equipos de desarrollo tienen que esforzarse para renovarse una y otra vez Maven vino a cubrir estos problemas que provenan del ciclo de vida de un proyecto. La construccin, la reutilizacin, la documentacin, la variedad de entornos en los que se puede desplegar.

1.1.

Descripcin del proyecto

Este proyecto trata de crear una arquitectura que simplifique el trabajo en Java. Creando una estructura que aporte el mayor nmero de soluciones en el menor cdigo posible. Multitud de proyectos los iniciados y creados a partir de cero, cuando se poda haber tenido una base con la que haber aligerado meses y meses de trabajo. En esencia se trata de dar el esqueleto de un cdigo en JAVA que instale y configure el proyecto con todos los frameworks y tecnologas necesarias. Se utiliza Maven para la instalacin y posterior mantenimiento del ciclo de vida de los proyectos que se creen con esta arquitectura.

1.2.

Antecedentes

Varias soluciones han sido expuestas desde diferentes sectores de la comunidad JAVA. Destacan soluciones como las de Netbeans o Eclipse, que intentan crear proyectos de determinado tipo desde su entorno con los que sus usuarios pueden empezar a trabajar. 7

Destaca tambin la aportacin de Matt Raible por sus arquetipos creados en Maven y sus arquitecturas para Ant creadas desde el ao 2005 al 2009.

1.3.

Objetivos

El principal objetivo es crear un arquetipo de Maven3 que integre una arquitectura innovadora y eficiente que ayude a la comunidad de programadores a iniciar y gestionar sus proyectos sin tanto esfuerzo. Se propone una arquitectura que rena las tecnologas ms vanguardistas. Buscando la sencillez, la abstraccin y reduciendo al mnimo el coste de inicio de un proyecto. Hay que integrar todos los framaworks que se necesiten para crear una arquitectura del tipo MVC (Modelo Vista Controlador) y despus crear un ejemplo de cada uno de ellos. El arquetipo deber de poder ser utilizado desde un repositorio pblico de Maven y poder ser descargado como un proyecto java para aquellos programadores que no tengan posibilidad de conectase a un servidor de Maven. Implementar un sistema de testeo que le aporte a los futuros proyectos que utilicen esta arquitectura cierta calidad en el cdigo. Se deber de ofrecer un testeo para pruebas unitarias, pruebas de integracin y para pruebas de stress. Junit, Jmock y Jmeter son en principio las herramientas que ms potencial tienen para entrar en la arquitectura. Todo el proyecto estar documentado en una wiki con acceso de cualquier usuario de Internet. La wiki servir para exponer el proyecto ante los desarrolladores y como manual de ayuda de nuestra arquitectura. Esto obligara a hacer un trabajo de mantenimiento para cubrir las posibles incidencias que tengan nuestros usuarios.

1.4.

Fases de trabajo

Las fases del proyecto se dividen en 6 partes: Anlisis de requisitos y captacin de documentacin. Documentar funcionalmente cada parte del proyecto. Crear un arquetipo en Maven que solucione las carencias que ahora tenemos. Desarrollar un ejemplo de cada tecnologa para que los usuarios asimilen lo antes posible la tecnologa. Transformar el proyecto en un arquetipo para Maven. Documentacin de la memoria.

1.5.

Estructura de la memoria

Inicialmente se explica que es un proyecto en el lenguaje JAVA y construido con la herramienta Maven para que el lector entienda los fundamentos del proyecto. Se continuar exponiendo los conceptos, framework y componentes que debera de conocer para utilizar de forma eficaz la arquitectura. Cuando se han aprendido todos los conceptos previos se puede presentar la arquitectura y seguir con un caso de ejemplo de cmo instalarla y utilizarla. Hay que sealar que la memoria no sirve de gua de ninguna herramienta que aqu se explica. Hay muchos manuales tanto impreso como por Internet que se puede consultar si se quiere profundizar ms en el tema. En el apartado de enlaces de esta memoria se puede consultar los ms importantes y investigar a partir de ellos. 8

1.6.

Requisitos

Requisitos software para el desarrollo del proyecto: Windows XP y Linux en la distribucin de Kubuntu. JDK 1.6 de JAVA Tortoise o plugin de eclipse 'subclipse' para la comunicacin con el repositorio. IDE Eclipse. O Netbeans Maven 3.0 Alta en el proyecto Google Code. Base de datos Mysql y Posgresql. Servidor de aplicaciones Jboss 6.0 Contenedor de serlets y jsp Apache Tomcat 7.0 Servidor Http Jetty 7.0

10

2. Arquitectura en JAVA con Maven


La finalidad del proyecto es crear un arquetipo que aporte al usuario una arquitectura con la que empezar a trabajar. Un arquetipo es un proyecto de JAVA, as que se va a empezar a definir que es JAVA y cual es la forma ptima de utilizarlo.

2.1.

Java

Java es un lenguaje de programacin orientado a objetos, basado en la sintaxis que defini el lenguaje C. Actualmente Java es el mximo exponente de los lenguajes orientados a objetos, no por su rendimiento frente a otros lenguajes sino por su movimiento hacia el sector de Internet. Fue creado por la empresa Sun Microsystems. En principio la principal motivacin de la empresa fue unificar en un lenguaje la multitud de arquitecturas incompatibles que estaban surgiendo. Despus el lenguaje tomo Internet como campo de batalla para crecer y hacerse fuerte. Java se cre originalmente como una herramienta de programacin para un proyecto set-top-box conocido como *7. Fue realizado por un equipo de 13 personas, dirigidas por James Gosling. Las principales ventajas de java son:

Robusto Dinmico Multiflujo Alto rendimiento Interpretado Portable Seguro Distribuido Orientado a objetos Dinmico No dependiente de la arquitectura

El programador escribe los ficheros de fuente java en un editor de texto y los guarda como ficheros *.java. El compilador de java los compila convirtindolos en ficheros *.class. Hasta aqu todo es igual que el resto de los lenguajes de programacin. Ahora es cuando entra en juego la Mquina Virtual de Java. El fichero *.class llega a la mquina virtual de java que se encarga de interpretar el programa y lo ejecuta. As se consigue que el programa se abstraiga de la arquitectura en la que est implantado dejndose esto en manos de la mquina virtual. Los principales navegadores de Internet y algunos sistemas operativos ya vienen con la mquina virtual de java instalados. Aunque siempre se le ofrece paquetes, a los usuarios de programas Java, que son accesibles desde la red y puede bajarse en http://sun.java.es 11

Si JAVA esta instalado hay muchas formas de utilizarlo. Las ms comunes son por applets que se ejecutan en un navegador, ejecutar un jar o ejecutar directamente una clase java. Las clases java se ejecutan desde las lneas de comando o desde IDE especializados (ms adelante se habla de los IDE y de su utilidad en la arquitectura). Lanzndolo desde la lnea de comando con la aplicacin javac. javac @options @classes Hay una serie de conceptos de JAVA que hay que conocer a la hora de trabajar con la arquitectura, en especial los Beans, los POJOS y los Frameworks.

2.1.1.

Frameworks

La palabra inglesa "framework" define, en trminos generales, un conjunto estandarizado de conceptos, prcticas y criterios para enfocar un tipo de problemtica particular, que sirve como referencia para enfrentar y resolver nuevos problemas de ndole similar. En el desarrollo de software, un framework es una estructura conceptual y tecnolgica de soporte definida, normalmente con artefactos o mdulos de software concretos, con base en la cual otro proyecto de software puede ser organizado y desarrollado. Tpicamente, puede incluir soporte de programas, bibliotecas y un lenguaje interpretado entre otros programas para ayudar a desarrollar y unir los diferentes componentes de un proyecto. [40]

2.1.2.

POJO

Un POJO (acrnimo de Plain Old Java Object) es una sigla creada por Martin Fowler, Rebecca Parsons y Josh MacKenzie en septiembre de 2000 y utilizada por programadores Java para enfatizar el uso de clases simples y que no dependen de un framework en especial. Este acrnimo surge como una reaccin en el mundo Java a los Frameworks cada vez ms complejos, y que requieren un complicado andamiaje que esconde el problema que realmente se est modelando. En particular surge en oposicin al modelo planteado por los estndares EJB anteriores al 3.0, en los que los "Enterprise JavaBeans" deban implementar interfaces especiales. [41]

2.1.3.

Beans

Un JavaBean o Bean es un objeto que sigue una serie de reglas que posibilitan su creacin, manejo y gestin en entornos principalmente visuales. Estas reglas son: Debe tener un constructor sin argumentos. Sus propiedades se hacen accesibles mediante mtodos get y set que siguen una nomenclatura establecida: getPropiedad() y setPropiedad(Tipo prop). Debe ser implementar la interfaz Serializable.

2.2.

Patrn de diseo
12

Es importante conocerlos para entender porque se utiliza determinada estructura o determinado framework en la arquitectura. Se exponen la definicin de los patrones y luego los patrones que ms se utilizan en JAVA, sobre todo para la versin J2EE, versin especializada en aplicaciones webs. El concepto de "patrn de diseo" que tenemos en Ingeniera del Software se ha tomado prestado de la arquitectura. En 1977 se publica el libro "A Pattern Language: Towns/Building/Construction", de Christopher Alexander, Sara Ishikawa, Murray Silverstein, Max Jacobson, Ingrid Fiksdahl-King y Shlomo Angel, Oxford University Press. Contiene numerosos patrones con una notacin especfica de Alexander. Alexander comenta que Cada patrn describe un problema que ocurre una y otra vez en nuestro entorno, para describir despus el ncleo de la solucin a ese problema, de tal manera que esa solucin pueda ser usada ms de un milln de veces sin hacerlo siquiera dos veces de la misma forma. El patrn es un esquema de solucin que se aplica a un tipo de problema, esta aplicacin del patrn no es mecnica, sino que requiere de adaptacin y matices. Por ello, dice Alexander que los numerosos usos de un patrn no se repiten dos veces de la misma forma. La idea de patrones de diseo estaba "en el aire", la prueba es que numerosos diseadores se dirigieron a aplicar las ideas de Alexander a su contexto. El catlogo ms famoso de patrones se encuentra en Design Patterns: Elements of Reusable Object-Oriented Software, de Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, 1995, Addison-Wesley, tambin conocido como el libro GOF (Gang-Of-Four). [37] Siguiendo el libro de GOF los patrones se clasifican segn el propsito para el que han sido definidos [37]: Patrones creacionales: solucionan problemas de creacin de instancias. Ayudan a encapsular y abstraer dicha creacin. o Abstract Factory (Fbrica abstracta): Permite trabajar con objetos de distintas familias de manera que las familias no se mezclen entre s y haciendo transparente el tipo de familia concreta que se est usando. o Builder (Constructor virtual): Abstrae el proceso de creacin de un objeto complejo, centralizando dicho proceso en un nico punto. o Factory Method (Mtodo de fabricacin): Centraliza en una clase constructora la creacin de objetos de un subtipo de un tipo determinado, ocultando al usuario la casustica para elegir el subtipo que crear. o Prototype (Prototipo): Crea nuevos objetos clonndolos de una instancia ya existente. o Singleton (Instancia nica): Garantiza la existencia de una nica instancia para una clase y la creacin de un mecanismo de acceso global a dicha instancia Patrones estructurales: solucionan problemas de composicin (agregacin) de clases y objetos. o Adapter(Adaptador): Adapta una interfaz para que pueda ser utilizada por una clase que de otro modo no podra utilizarla. o Bridge(Puente): Desacopla una abstraccin de su implementacin. o Composite(Objeto compuesto): Permite tratar objetos compuestos como si de uno simple se tratase. o Decorator(Envoltorio): Aade funcionalidad a una clase dinmicamente. o Facade (Fachada): Provee de una interfaz unificada simple para acceder a una interfaz o grupo de interfaces de un subsistema. o Flyweight(Peso ligero): Reduce la redundancia cuando gran cantidad de objetos 13

poseen idntica informacin. o Proxy: Mantiene un representante de un objeto Patrones de comportamiento: soluciones respecto a la interaccin y responsabilidades entre clases y objetos, as como los algoritmos que encapsulan. o Chain of Responsibility (Cadena de responsabilidad): Permite establecer la lnea que deben llevar los mensajes para que los objetos realicen la tarea indicada. o Command(Orden): Encapsula una operacin en un objeto, permitiendo ejecutar dicha operacin sin necesidad de conocer el contenido de la misma. o Interpreter (Intrprete): Dado un lenguaje, define una gramtica para dicho lenguaje, as como las herramientas necesarias para interpretarlo. o Iterator(Iterador): Permite realizar recorridos sobre objetos compuestos independientemente de la implementacin de estos. o Mediator (Mediador): Define un objeto que coordine la comunicacin entre objetos de distintas clases, pero que funcionan como un conjunto. o Memento(Recuerdo): Permite volver a estados anteriores del sistema. o Observer (Observador): Define una dependencia de uno-a-muchos entre objetos, de forma que cuando un objeto cambie de estado se notifique y actualicen automticamente todos los objetos que dependen de l. o State (Estado): Permite que un objeto modifique su comportamiento cada vez que cambie su estado interno. o Strategy (Estrategia): Permite disponer de varios mtodos para resolver un problema y elegir cul utilizar en tiempo de ejecucin. o Template Method (Mtodo plantilla): Define en una operacin el esqueleto de un algoritmo, delegando en las subclases algunos de sus pasos, esto permite que las subclases redefinan ciertos pasos de un algoritmo sin cambiar su estructura. o Visitor(Visitante): Permite definir nuevas operaciones sobre una jerarqua de clases sin modificar las clases sobre las que opera.

2.2.1.

Patrn MVC

Modelo Vista Controlador (MVC) es un patrn de arquitectura de software que separa los datos de una aplicacin, la interfaz de usuario, y la lgica de control en tres componentes distintos. Fue descrito por primera vez en 1979 por Trygve Reenskaug, trabajador de Smalltalk, en unos laboratorios de investigacin de Xerox. El patrn MVC se ve frecuentemente en aplicaciones web, donde la vista es la pgina HTML y el cdigo que provee de datos dinmicos a la pgina, el modelo es el Sistema de Gestin de Base de Datos y la Lgica de negocio y el controlador es el responsable de recibir los eventos de entrada desde la vista [38] Las funcionalidades de las diferentes capas son [39]: El modelo es el responsable de: o Acceder a la capa de almacenamiento de datos. Lo ideal es que el modelo sea independiente del sistema de almacenamiento.

14

o Define las reglas de negocio (la funcionalidad del sistema). Un ejemplo de regla puede ser: "Si la mercanca pedida no est en el almacn, consultar el tiempo de entrega estndar del proveedor". o Lleva un registro de las vistas y controladores del sistema. o Si estamos ante un modelo activo, notificar a las vistas los cambios que en los datos pueda producir un agente externo (por ejemplo, un fichero bath que actualiza los datos, un temporizador que desencadena una insercin, etc). El controlador es responsable de: o Recibe los eventos de entrada (un clic, un cambio en un campo de texto, etc.). o Contiene reglas de gestin de eventos, del tipo "SI Evento Z, entonces Accin W". Estas acciones pueden suponer peticiones al modelo o a las vistas. Una de estas peticiones a las vistas puede ser una llamada al mtodo "Actualizar ()". Una peticin al modelo puede ser "Obtener_tiempo(nueva_orden)". Las vistas son responsables de: o Recibir datos del modelo y mostrarlos al usuario. o Tienen un registro de su controlador asociado (normalmente porque adems lo instancia). o Pueden dar el servicio de "Actualizacin ()", para que sea invocado por el controlador o por el modelo (cuando es un modelo activo que informa de los cambios en los datos producidos por otros agentes).

Se puede ver mejor el comportamiento de un sistema que utilice el patrn MVC mediante un diagrama de secuencias:

Figura X. Diagrama de secuencia del patrn MVC. [39] Describiendo los pasos en el MVC: El usuario introduce el evento. El controlador recibe el evento y lo traduce en una peticin al Modelo (aunque tambin puede llamar directamente a la vista). El modelo (si es necesario) llama a la vista para su actualizacin. Para cumplir con la actualizacin la Vista puede solicitar datos al Modelo. El Controlador recibe el control.

15

2.2.2.

Patrones J2EE

Con la aparicin del J2EE, todo un nuevo catlogo de patrones de diseo apareci. Desde que J2EE es una arquitectura por si misma que involucra otras arquitecturas, incluyendo servlets, JavaServer Pages, Enterprise JavaBeans, y ms, merece su propio conjunto de patrones especficos para diferentes aplicaciones empresariales. [42] De acuerdo al libro "J2EE PATTERNS Best Practices and Design Strategies", existen 5 capas en la arquitectura J2EE:

Cliente Presentacin Negocios Integracin Recurso

El libro explica 15 patrones J2EE que estn divididos en 3 de las capas: presentacin, negocios e integracin. Patrones de la capa de presentacin: Decorating Filter / Intercepting Filter Un objeto que est entre el cliente y los componentes Web. Este procesa las peticiones y las respuestas. Un objeto que acepta todos los requerimientos de un cliente y los direcciona a manejadores apropiados. El patrn Front Controller podra dividir la funcionalidad en 2 diferentes objetos: el Front Controller y el Dispatcher. En ese caso, El Front Controller acepta todos los requerimientos de un cliente y realiza la autenticacin, y el Dispatcher direcciona los requerimientos a manejadores apropiada. Un objeto helper que encapsula la lgica de acceso a datos en beneficio de los componentes de la presentacin. Por ejemplo, los JavaBeans pueden ser usados como patrn View Helper para las pginas JSP. Un objeto vista que est compuesto de otros objetos vista. Por ejemplo, una pgina JSP que incluye otras pginas JSP y HTML usando la directiva include o el action include es un patrn Composite View. Es como el patrn de diseo MVC con el Controlador actuando como Front Controller pero con una cosa importante: aqu el Dispatcher (el cual es parte del Front Controller) usa View Helpers a gran escala y ayuda en el manejo de la vista. Es como el patrn de diseo MVC con el controlador actuando como Front Controller pero con un asunto importante: aqu el Dispatcher (el cual es parte del Front Controller) no usa View Helpers y realiza muy poco trabajo en el manejo de la vista. El manejo de la vista es manejado por los mismos componentes de la Vista.

Front Controller/ Front Component

View Helper

Composite view

Service To Worker

Dispatcher View

Tabla X. Patrones de la capa de presentacin. Patrones de la capa de negocios: 16

Business Delegate Value Object/ Data Transfer Object/ Replicate Object Session Faade/ Session Entity Faade/ Distributed Faade Aggregate Entity Value Object Assembler Value List Handler/ Page-by-Page Iterator/ Paged List

Un objeto que reside en la capa de presentacin y en beneficio de los otros componentes de la capa de presentacin llama a mtodos remotos en los objetos de la capa de negocios. Un objeto serializable para la transferencia de datos sobre lar red. El uso de un bean de sesin como una fachada (facade) para encapsular la complejidad de las interacciones entre los objetos de negocio y participantes en un flujo de trabajo. El Session Faade maneja los objetos de negocio y proporciona un servicio de acceso uniforme a los clientes. Un bean entidad que es construido o es agregado a otros beans de entidad. Un objeto que reside en la capa de negocios y crea Value Objets cuando es requerido. Es un objeto que maneja la ejecucin de consultas SQL, cach y procesamiento del resultado. Usualmente implementado como beans de sesin. Consiste en utilizar un objeto Service Locutor para abstraer toda la utilizacin JNDI y para ocultar las complejidades de la creacin del contexto inicial, de bsqueda de objetos home EJB y recreacin de objetos EJB. Varios clientes pueden reutilizar el objeto Service Locutor para reducir la complejidad del cdigo, proporcionando un punto de control.

Service Locator

Tabla X. Patrones de la capa de negocios. Patrones de la capa de integracin: Data Access Object Service Activator Consiste en utilizar un objeto de acceso a datos para abstraer y encapsular todos los accesos a la fuente de datos. El DAO maneja la conexin con la fuente de datos para obtener y almacenar datos.

Se utiliza para recibir peticiones y mensajes asncronos de los clientes. Cuando se Service Activator recibe un mensaje, el Service Activator localiza e invoca a los mtodos de los componentes de negocio necesarios para cumplir la peticin de forma asncrona. Tabla X. Patrones de la capa de integracin.

2.2.3.

Patrn de inversin de control

Inversin de control (Inversion of Control en ingls, IoC) es un mtodo de programacin en el que el flujo de ejecucin de un programa se invierte respecto a los mtodos de programacin tradicionales, en los que la interaccin se expresa de forma imperativa haciendo llamadas a procedimientos (procedure calls) o funciones. Tradicionalmente el programador especifica la secuencia de decisiones y procedimientos que pueden darse durante el ciclo de vida de un programa mediante llamadas a funciones. En su lugar, en la inversin de control se especifican respuestas 17

deseadas a sucesos o solicitudes de datos concretas, dejando que algn tipo de entidad o arquitectura externa lleve a cabo las acciones de control que se requieran en el orden necesario y para el conjunto de sucesos que tengan que ocurrir. El flujo habitual se da cuando es el cdigo del usuario quien invoca a un procedimiento de una biblioteca. La inversin de control sucede cuando es la biblioteca la que invoca el cdigo del usuario. La utilizacin de interfaces y la aparicin de los frameworks han popularizado este trmino. De hecho es el concepto central del Framework de Spring, ya que implementa un "Contenedor" que se encarga de gestionar las instancias (as como sus creaciones y destrucciones) de los objetos del usuario. Por tanto las aplicaciones que utilicen el framework de Spring (no Spring propiamente dicho) utilizarn Inversin de Control. [44]

2.2.4.

Patrn de inyeccin de dependencias

En Informtica, Inyeccin de Dependencias (en ingls Dependency Injection, DI) es un patrn de diseo orientado a objetos, en el que se suministran objetos a una clase en lugar de ser la propia clase quien cree el objeto. El trmino fue acuado por primera vez por Martin Fowler. Tpicamente este contenedor es implementado por un framework externo a la aplicacin (como Spring o uno propietario), por lo cual en la aplicacin tambin se utilizar Inversin de Control al ser el contenedor (almacenado en una biblioteca) quien invoque el cdigo de la aplicacin. sta es la razn por la que los trminos de Inversin de Control e Inyeccin de Dependencias se confunden habitualmente entre s. [45]

2.3.

Maven

El arquetipo va a ser un proyecto en JAVA pero es un tipo de proyecto especial ya que sigue una determinado estructura y caractersticas que exige Maven. Se va a describir para que sirve y como utilizar Maven. Maven es una herramienta para la gestin del ciclo de vida de las aplicaciones. Funciona como una aplicacin en Java y es un Opensource de la fundacin Apache. Bajo una licencia Apache Licence 2.0. Pero que es gestionar el ciclo de vida de un software? Maven tiene las virtudes de poder crear un proyecto o descargrselo de algn repositorio, construirlo, definir las dependencias, integrar el proyecto con los IDE's, compilacin, empaquetado, pruebas unitarias, pruebas de estrs y funcionalidad, calidad y documentacin del cdigo. Maven tiene su opositor en Ant tambin de Apache. Ant tiene menos funcionalidad que Maven es ya que solo es un constructor de proyectos, una funcionalidad de las muchas que tiene Maven. Es fcil pensar que Maven es un complemento de Ant, al tener ms funcionalidad y por poder invocarse desde Maven. 18

Las ventajas de Maven en la produccin de proyectos software: Hacer el proceso de construccin fcil. Proveer un proceso de construccin uniforme. Proveer una cantidad de informacin sobre el proyecto. Servir como gua de buenas practicas de desarrollo de software. Permitir una migracin transparente a nuevas funcionalidades. Setup simple de proyectos siguiendo buenas practicas de software. Generar un proyecto nuevo en pocos segundos. Manejo de dependencias incluyendo actualizaciones automticas. Tanto dependencias primarias como transitivas. Permite trabajar de una forma fcil con mltiples proyectos al mismo tiempo. Grande y creciente repositorio de libreras y metadatos externo a nuestro proyecto. Liberando as el sistema de control de versiones de contener jars. Es extensible. Haciendo uso de sus sistema de plugins en java o en lenguajes de scripts. Acceso instantneo a nueva funcionalidades con una mnima o ninguna configuracin. Posibilidad del uso de tareas ant para manejar dependencias y despliegue fuera de Maven. Maven esta preparado para un gran nmero de builds para proyectos, ya sea tipo jar, war, ear. Usando los metadatos asociados al proyecto, Maven es genera un sitio web o pdf incluyendo cualquier documentacin que se quiera. Adems de toda la informacin que Maven aade como api, java doc, informacin sobre desarrolladores, informes de test, etc. Manejo de release y publicacin de distribuciones. Maven pude ser integrado con el sistema de control de versiones y manejar las releases de un proyecto en un tag concreto. Maven puede publicar distribuciones basadas en jar, en un archivo incluyendo dependencias y documentacin, o una distribucin de fuentes. Manager de dependencias: Maven impulsa el uso de un repositorio central de JARs y otras.

Los inconvenientes de Maven en la gestin de proyectos software: Su curva de aprendizaje es muy pronunciada. Los informticos que desarrollen el proyecto deben de estar muy preparados en conocimientos de Java. A continuacin se van a describir unos conceptos importantes de Maven: Los ficheros POM (Project Object Model) son ficheros en formato XML obligatorio en todo proyecto Maven, donde se incluye la informacin (meta-datos) necesaria para que ste pueda construir y gestionar el proyecto. Artefacto: Es para Maven la unidad mnima con la que trabaja a la hora de gestionar sus dependencias. Coordenadas: Sistema con el Maven determina de forma nica a cada uno de sus artefactos. Goal: Son las unidades de mnimas de ejecucin. Las tareas ms simples. Ciclo de vida: Secuencia de etapas que propone Maven para la gestin de un proyecto.

Las fases del ciclo de vida de Maven son [8]: pre-clean: ejecuta los procesos necesarios para la limpieza. clean: elimina todos los ficheros generados en la construccin previa. post-clean: ejecuta los procesos necesarios al finalizar la limpieza del proyecto. validate: valida que el proyecto es correcto y tiene toda la informacin necesaria. 19

inicializate: Inicializa la construccin, modificando propiedades o creando directorios. generate-sources: Genera algn cdigo fuente para utilizarlo en la compilacin. process-sources: Procesa el cdigo fuente anterior. generate-resources: Genera los recursos para incluirlos en el paquete. process-resources: Copia y procesa los recursos al directorio de trabajo. compile: Compila el cdigo fuente. process-classes: Ejecuta unas tareas despus del la generacin de los cdigos compilados, por ejemplo por si hubiera que cambiar el bytecode de las clases. generate-test-sources: Genera algunos cdigos fuentes de los test para la inclusin en la compilacin. process-test-sources: Procesa el cdigo fuente de los test, por ejemplo filtrar algunas variables. generate-test-resources: Crea los recursos para el test. process-test-resources: Copia y procesa los recursos dentro del directorio destino de los test. test-compile: Compila el cdigo fuente de los test dentro del directorio destino de los test. process-test-classes: Hace un postprocesado de la generacin de ficheros de la compilacin de los test. Por ejemplo se cambia el bytecode. test: compila el cdigo y ejecuta los unit test correspondientes. Sin embargo no es requisito para que el proyecto sea desplegado. prepare-package: Prepara algunas operaciones necesarias antes del empaquetado. package: toma el cdigo compilado y lo empaqueta en un formato distribuible como JAR o WAR. pre-integration-test: prepara algunas operaciones antes que se ejecuten los test de integracin. integration-test: Despliega el proyecto si es necesario en ambiente de pruebas donde se puedan correr pruebas de integracin. post-integration-test: prepara algunas operaciones despus que se ejecuten los test de integracin. Esto puede incluir la limpieza del entorno. verify: ejecuta cualquier verificacin para cumplir los parmetros de calidad. install: instala el jar o war en el repositorio local para que otras aplicaciones locales la puedan usar. deploy: copia el jar o war a un repositorio remoto para que pueda ser usado por otro desarrollador o proyecto. pre-site: ejecuta los procesos necesarios para la generacin del site. site: genera la documentacin del site proyecto post-site: ejecuta los procesos necesarios al finalizar la documentacin del site y prepara para el despliegue. site-deploy: despliega la generacin del site al servidor especificado.

20

Figura X. Ciclo de vida de Maven 3. [46] Estructura de directorios: Propuesta que realiza Maven para organizar los distintos archivos que conforman un proyecto. Los proyectos en Maven siempre marcan una determinada estructura, esto simplifica el trabajo a la hora de migrar un equipo de desarrollo a otro proyecto de Maven, ya que todos mantienen las mismas pautas. La estructura estndar de un proyecto en Maven es: Directorio /aplicacion/pom.xml /aplicacion/src/ /aplicacion/src/main/java/ /aplicacion/src/test/java/ /aplicacion/src/main/resources/ /aplicacion/src/test/resources/ /aplicacion/src/main/webapp /aplicacion/target/classes/ /aplicacion/target/test-classes/ /aplicacion/target/dots /aplicacion/target/{#filename} Descripcin Fichero de configuracin de Maven Cdigo fuente Cdigo fuente de java Test de JUnits Recursos necesarios en el classpath Recursos necesarios en el classpath para los test Contiene los html, jsp y dems contenidos de una aplicacin web Clases ya compiladas Las clases de los test ya compiladas Otras salidas de documentos En los proyectos war tienen el contenido de la creacin del war

Tabla X. Estructura de carpetas de un proyecto Maven. 21

Archetype: Son plantillas con las definir la base de proyectos tipo con el fin de reutilizarlas. Los archetype son simples plugins de Maven, uno de ellos es el archetype create, el cual permite crear un proyecto base al proporcionar la plantilla del mismo. El archetype create recibe una serie de parmetros los cuales son: archetypeGroupId: Identificador del grupo del archetipo. groupId, es usado como identificador del conjunto de libreras en este caso hemos usado org.archetypeUma como nombre para nuestro paquete de libreras. artifactId, es usado como identificador particular de una librera en particular.

Cuando se usan archetypes creados por uno mismo se tiene que especificar los tres parmetros de todo archetype (groupId, artifactId, version) de la siguiente manera. mvn archetype:create -DarchetypeGroupId=<archetype-groupId> -DarchetypeArtifactId=<archetype-artifactId> -DarchetypeVersion=<archetype-version> -DgroupId=<my.groupid> -DartifactId=<my-artifactId> Si es la primera vez que se ejecuta un comando Maven ste tomar algo de tiempo pues Maven crear el repositorio inicial .m2 y descargar todas las libreras necesarias para construir el proyecto. En este caso el archetype contiene la plantilla de un proyecto web. Finalizado el proceso de construccin del artefacto, Maven lo deposita en repositorios. Repositorio: Estructura de directorios y archivos que usa Maven para almacenar, organizar y recuperar artefactos. Existen repositorios locales (file://) y remotos (http://) Existen dos tipo de repositorios: o Repositorio local: situado en la mquina del desarrollador. Almacena artefactos instalados (Maven install) y descargados de repositorios remotos. o Repositorio remotos: repositorios accesibles a travs de protocolos file:// y http://. internos: utilizados por las empresas para almacenar sus artefactos que son compartidos por los desarrolladores. externos: repositorios pblicos utilizados para almacenar artefactos de terceros.

Hay varias herramientas que permiten gestionar un repositorio. Si el lector esta interesado en profundizar en el tema le aconsejamos que siga por Archiva o Artefactory, que son software libre muy utilizado. Profiles: Son un mecanismo (no alternativa) de configurar el proceso de construccin. En ciertos proyectos es importante trabajar con varias bases de datos, en varios entornos diferentes o en varios servidores. Las libreras y las variables de configuracin que se necesitan para arrancar en cada entorno son diferentes. Maven resuelve esto mediante profiles: <profiles> <profile> <id>mysql</id> <activation> <property> 22

<name>db</name> <value>mysql</value> </property> </activation> <properties> <driver>org.mysql.Driver</driver> </properties> </profile> <profile> <id>postgresql</id> <activation> <property> <name>db</name> <value>postgresql</value> </property> </activation> <properties> <driver>org.postgresql.Driver</driver> </properties> </profile> </profiles> Basta con pasarle a Maven con que perfil quiere instalar. mvn -Pmysql clean Los perfiles en la versin 3 de Maven hay que meterlos en el fichero M2_HOME/conf/settings.xml, antes Maven acostumbraba meterlos en un fichero profiles.xml que acompaaba al pom.xml principal. Los tag ms importantes en el uso de Maven son: <groupId>: El id del grupo al que pertenece el proyecto. <artifactId>: El id del artifact o proyecto (en la mayora de los casos el nombre del proyecto). <version>: La versin del artifact en el grupo especificado.

<groupId>org.archetypeUma</groupId> <artifactId>archetypeUma-model</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> Lo de -SNAPSHOT en el nombre de la versin hay que explicarlo detalladamente. Si dependemos de un jar que tenga -SNAPSHOT, cada vez que compilemos, aunque ese jar est en nuestro repositorio local, Maven ira a buscarlos a los repositorios comunes o de Internet, para ver si hay una versin de fecha ms moderna. Si la hay, se la bajar. Por tanto, suele ser til en un equipo de trabajo mantener la "coletilla" -SNAPSHOT en los jar que todava estn en desarrollo y sufren cambios frecuentes. Si no ponemos -SNAPSHOT, una vez bajado el jar a nuestro repositorio local, Maven NO se preocupar de buscar si hay versiones ms modernas en los repositorios remotos. 23

En los poms se pueden definir muchos componentes. Se van a explicar los que han sido utilizados para crear esta arquitectura y los ms utilizados. Empezando por developers, sirve para especificar los desarrolladores y el equipo que ha intervenido en el proyecto. <developers> <developer> <id>jcisneros</id> <name>Javier Cisneros Gonzlez</name> <email>javicisneros@gmail.es</email> </developer> </developers> scm: son las siglas de Source Code Management (Gestin de cdigo fuente), es la revisin de mltiples versiones de una misma unidad de informacin. Con el siguiente XML se especifica donde esta el cdigo del proyecto. Esto no es obligatorio pero si es muy guardarlo en el pom principal del proyecto. <scm> <connection>scm:svn:https://archetypeuma.googlecode.com/svn/trunk/</connection> <developerConnection>scm:svn:https://archetypeuma.googlecode.com/svn/trunk/ </developerConnection> <url></url> </scm> licenses: Las licencias del proyecto se marcan bajo la etiqueta XML llamada licences. En las siguientes lneas se especifica que el proyecto ser de software libre bajo la licencia Apache License 2.0 y European Union Public License. <licenses> <license> <name>EUPL v1.0</name> <url>http://ec.europa.eu/idabc/eupl</url> <comments>European Union Public License</comments> </license> <license> <name>Apache License 2.0</name> <url>http://www.apache.org/licenses/LICENSE-2.0</url> <comments /> </license> </licenses> modules: La etiqueta module asigna al pom los submodulos que se ejecutarn despus de ejecutarse el mismo. Es ideal para lanzar una construccin en varios modulos, ya que crearlo en uno solo puede resultar muy engorroso. <modules> <module>model</module> <module>core</module> <module>web</module> </modules>

24

repositories: Maven se baja las dependencias de los servidores que sirven de repositorios. Esos repositorios pueden estar en cualquier sitio de Internet o de una red local. Hay que especificarle al proyecto donde estn los repositorios desde los que se quiere descargar las dependencias del proyecto. En el siguiente ejemplo se utiliza el repositorio pblico de Jboss. <repositories> <repository> <id>jboss</id> <name>JBoss repository</name> <url>http://repository.jboss.org/Maven2</url> </repository> </repositories> pluginRepositories: Al igual que el caso anterior, Maven busca los plugins en los repositorios remotos, en lugar de apuntar con la etiqueta repositories, se utiliza pluginRepositories. <pluginRepositories> <pluginRepository> <id>appfuse</id> <url>http://static.appfuse.org/repository</url> </pluginRepository> <pluginRepository> <id>alfresco</id> <url>http://Maven.alfresco.com/nexus/content/repositories/sourcesense-public</url> </pluginRepository> <pluginRepository> <id>Maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/Maven/2/</url> <layout>default</layout> </pluginRepository> <pluginRepository> <id>mc-release</id> <name>Local Maven repository of releases</name> <url>http://mc-repo.googlecode.com/svn/Maven2/releases</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </pluginRepository> <pluginRepository> <id>repo1</id> <name>Repo-1 for Maven 2</name> <url>http://repo1.Maven.org/Maven2/</url> <layout>default</layout> 25

</pluginRepository> </pluginRepositories> resources: Se especifica los recursos que necesitarn las clases java para funcionar correctamente. Aqu caben muchas posibilidades... plantillas, xml, ficheros estticos. Se suele poner el fichero de recursos de Maven src/main/resources. Al meterlo se empaquetara en el jar, war o ear como un fichero ms. <resources> <resource> <filtering>true</filtering> <directory>src/main/resources</directory> </resource> </resources> testResources: Se especifica con testResources cual ser el directorio de recursos para los test. Es decir, que si un test necesita determinado fichero para utilizar, por ejemplo un xml, este se buscar en estos directorios. <testResources> <testResource> <filtering>true</filtering> <directory>src/test/resources</directory> </testResource> </testResources> dependency: Los proyectos en Java se han llenado de libreras que tienen que interactuar entre si para formar los proyectos, lo ms abstractos posibles. Solo hay que especificar el groupId el artifactId y la versin que se desea descargar. Este es un ejemplo de como aadir una dependencia a un pom.xml en un proyecto de Maven. <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> </dependency> groupId: es usado como identificador del conjunto de libreras en este caso se ha usado log4j como nombre para nuestro paquete de libreras. artifactId: es usado como identificador particular de una librera en particular. Como log4j solo tiene una coincide con el groupId pero esto no debe porque ser as. version: Es la versin de la librera que se desea meter como dependencia en el proyecto. scope: es la fase del ciclo de vida de Maven a la que se le asociar la dependencia. Existen seis mbitos en los que una dependencia puede ser declarada limitando as su transitividad: o Compile, es el mbito por defecto. Las dependencias estn disponibles en el proyecto y en sus proyectos dependientes. o Provided, se espera que el JDK, la aplicacin o el contenedor provea la dependencia. o Runtime, la dependencia no es requerida en tiempo de compilacin pero s para la ejecucin. o Test, son dependencias que son requeridas solo cuando se compila y ejecuta los test. o System, similar a provided pero se le debe indicar el jar que contiene la dependencia 26

o Import, (a partir a la version 2.0.9) solo es usado en una dependencia del tipo POM en la seccin . Indica que el POM utilizado debe ser remplazado con las dependencias que ste tenga en su seccin <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.9.0.GA</version> <scope>runtime</scope> </dependency> En el scope se aade runtime para que la dependencia este presente solo en el empaquetado final del proyecto. Ya que no es necesaria ni a la hora de compilar, ni para los test ni en el resto de fases del ciclo de vida de Maven. <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.5</version> <scope>test</scope> </dependency> En este scope le pasamos como argumento test, ya que solo ser necesario en la fase de test y este jar no deber de estar presente en el empaquetado final del proyecto, ni en el war ni en el ear. La nomenclatura de las dependencias es la siguiente: artetifacId version package(jar, war, aer) En un ejemplo myfaces-core-2.0.0.jar La versin corresponde a mayor minor parches en este caso 2.0.0 Segunda versin, an sin cambios y sin parches arreglados. Un plugin es un programa que se ejecuta en Maven. Partiendo del ejemplo de compilar, solo es necesario tener el plugin de Maven-compiler-plugin en el pom.xml para que se compilara el proyecto. Hay muchos tipos de plugins y es perfectamente ampliable por cada usuario que necesite alguna funcionalidad que no este creada. <plugin> <groupId>org.apache.Maven.plugins</groupId> <artifactId>Maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> En la siguiente tabla se muestra una serie de plugins muy utilizados en los proyectos que se estn utilizando hoy en da.

27

Pluguins ms utilizados Maven-clean-plugin Maven-compiler-plugin Maven-deploy-plugin Maven-install-plugin Maven-resources-plugin Maven-site-plugin Maven-surefire-plugin

Descripcin Limpia el directorio de trabajo. Compila el cdigo fuente. Despliega el artefacto en un servidor remoto. Instala el artefacto en el repositorio local. Copia los recursos al directorio de salida. Genera el site del proyecto Ejecuta los test de Junit

Tabla X. Plugin ms utilizados de Maven. A continuacin se describen las rdenes ms importantes de Maven que todo aquel que trabaje con esta herramienta debe de conocer: Comando mvn version mvn clean mvn help mvn -X mvn test mvn package mvn install mvn deploy mvn dependency:tree mvn dependency:resolve mvn clean install -o -DMaven.test.skip=true Descripcin Ver la versin de Maven. Limpiar el directorio de trabajo de Maven de un proyecto es sencillo solo hay que aadir clean. El directorio de trabajo es la carpeta target. Mostrar la ayuda de Maven con el comando. Si hay algn problema y ha salido el mensaje BUILD FAILURE se puede comprobar que ha pasado escribiendo -X con lo que se ven las trazas en modo DEBUG. Ejecutar la fase del ciclo de vida de Maven referente a los test. Empaquetar en un jar, war o un ear. No instala los empaquetados en el repositorio local ni remoto. Instalar en el repositorio. Compila el proyecto, ejecuta los test, empaqueta los war y ear e instala el artefacto en el repositorio local de Maven. (%M2_REPO%) Si lo que se pretende es instalar en un repositorio remoto en vez de en el local. Se ejecuta un deploy. Esto tendra que hacerlo un sistema de integracin continua como es Hudson. Obtener el rbol de dependencias y optimizarlas para excluir las que no se necesiten. Muestra una listado de todos los artefactos que han sido resueltos. En un equipo de desarrollo la orden ms utilizada es la compilacin, empaquetado e instalacin. Con el argumento -o seleccionamos el modo offline. Algo que ser til en el equipo de desarrollo cada vez que se compile, ya que no se perder tiempo en conectarse con los repositorios externos. Con el argumento -DMaven.test.skip=true salta en el al ciclo de vida la fase de test y por tanto todos los plugins asociados a este ciclo de vida. Al igual que el argumento anterior esto har que se compile ms rpidamente el proyecto. Compila los fuentes del proyecto. Crea un proyecto en eclipse a partir de un proyecto Maven. Crea un proyecto en Intellij IDEA a partir de un proyecto Maven.

mvn compile mvn eclipse:eclipse mvn idea:idea

Tabla X. Comandos ms importantes de Maven. 28

3. Frameworks necesarios en la arquitectura


3.1. ORM
El mapeo objeto-relacional (ms conocido por su nombre en ingls, Object-Relational mapping, o sus siglas O/RM, ORM, y O/R mapping) es una tcnica de programacin para convertir datos entre el sistema de tipos utilizado en un lenguaje de programacin orientado a objetos y el utilizado en una base de datos relacional, utilizando un motor de persistencia. En la prctica esto crea una base de datos orientada a objetos virtual, sobre la base de datos relacional. Esto posibilita el uso de las caractersticas propias de la orientacin a objetos (bsicamente herencia y polimorfismo). Hay paquetes comerciales y de uso libre disponibles que desarrollan el mapeo relacional de objetos, aunque algunos programadores prefieren crear sus propias herramientas ORM. [48] El ORM ms utiliza en la actualidad es Hibernate.

3.1.1.

Hibernate

Hibernate es un ORM para Java. Es una capa de persistencia objeto/relacional y un generador de sentencias sql. Permite disear objetos persistentes que podrn incluir polimorfismo, relaciones, colecciones, y un gran nmero de tipos de datos. De una manera muy rpida y optimizada puede generar BBDD en cualquiera de los entornos soportados: Oracle, DB2, MySql, Postgresql. Es software libre y su cdigo es abierto, bajo licencia LGPL. Actualmente el proyecto pertenece a Red Hat pero esta cedido a la fundacin Apache. Fue creado en 2001 por Gavin King. Un ORM es una tecnologa capaz de entender que una clase de Java se corresponde con una tabla de la base de datos y que un objeto de Java se corresponde con una tupla de la base de datos. Hibernate ha estado mejorando. La mejora ms significativa la consigui cuando cambio los engorrosos XML por anotaciones, despus de que saliera el estndar JPA. El estndar JPA (Java Persistence API) fue descrito en la Java Specification Request (JSR) 220. Con el fin de meter al lector en conocimiento de la utilizad de Hibernate se va a exponer un ejemplo de como se insertaba un usuario en base de datos antes de Hibernate y despus de Hibernate. Sin Hibernate: Class.forName(org.hsqldb.jdbcDriver); String url = jdbc:hsqldb:./Databases/ejemplo; Connection connection = DriverManager.getConnection(url, root, pass); String ins = INSERT INTO TABLE_USER VALUES(jcisneros, javier); Statement stmt = null; stmt = connection.createStatement(); stmt.executeUpdate(ins); Con Hibernate y Spring: User user = new User(jcisneros, javier); userDao.save(user);

Hibernate funciona con dos tipos de anotaciones. Las suyas propias y las que provienen del estndar 29

JPA. Las del estndar son suficientes para la mayora de las aplicaciones que se quieran producir y las de Hibernate aaden funcionalidad para problemas ms concretos. El HQL (Hibernate Query Language) es un lenguaje de interrogacin. En el mundo relacional se rige por el SQL (Structured Query Language) que permite obtener informacin haciendo preguntas basadas en las tablas y sus columnas. El equivalente en el mundo actual es el HQL, que permite hacer preguntas basadas en los objetos y sus propiedades. Hibernate se encarga traducir las consultas desde las clases en HQL al lenguaje de interrogacin de la base de datos relacional, el SQL, y transforma los resultados obtenidos en la base de datos relacional (filas y columnas) en objetos de Java. Adems, Hibernate hace uso de APIs de Java, tales como JDBC, JTA (Java Transaction Api) y JNDI (Java Naming Directory Interface). Los objetos ms importantes definidos en Hibernate son: La interfaz Session es una de las interfaces primarias en cualquier aplicacin Hibernate. Una instancia de Session es "poco pesada" y su creacin y destruccin es muy "barata". Esto es importante, ya que la aplicacin necesitar crear y destruir sesiones todo el tiempo, quiz en cada peticin. Puede ser til pensar en una sesin como en una cach o coleccin de objetos cargados (desde una base de datos) relacionados con una nica unidad de trabajo. Hibernate puede detectar cambios en los objetos pertenecientes a una unidad de trabajo. La interfaz SessionFactory permite obtener instancias Session. Esta interfaz no es "ligera", y debera compartirse entre muchos hilos de ejecucin. Tpicamente hay una nica SessionFactory para toda la aplicacin, creada durante la inicializacin de la misma. Sin embargo, si la aplicacin accede a varias bases de datos se necesitar una SessionFactory por cada base de datos. La interfaz Configuration se utiliza para configurar y "arrancar" Hibernate. La aplicacin utiliza una instancia de Configuration para especificar la ubicacin de los documentos que indican el mapeado de los objetos y propiedades especficas de Hibernate, y a continuacin crea la sessionFactory. La interfaz Query permite realizar peticiones a la base de datos y controla cmo se ejecuta dicha peticin (query). Las peticiones se escriben en HQL o en el dialecto SQL nativo de la base de datos que estemos utilizando. Una instancia Query se utiliza para enlazar los parmetros de la peticin, limitar el nmero de resultados devueltos por la peticin, y para ejecutar dicha peticin.

Si se quiere llegar a entender el funcionamiento de hibernate hay que empezar por comprender el ciclo de vida que sigue un objeto que es manipulado por hibernate.

30

Figura X. Ciclo de vida de Hibernate. [50] Los estados son Transient, Persistent y Detached y los procesos por los que cambia de estado un objeto son esos mtodos que se invocan desde el cdigo y que hacen que el objeto cambie. El estado ms importante es el de Persistent al que se llega cuando se invoca un save sobre el objeto. A conticuacin se listan las anotaciones ms utilizadas: Anotacin Descripcin @Entity Declara la entidad que ser persistida @Table(name=TABLE_USER); Asigna el nombre de la tabla @Id Representa la clave primaria de la tabla @GeneratedValue Gener la clave primaria, en esta ocasin se crear una secuencia, pero hibernate da varias posibilidades. @Lob Corresponden a los campos del tipo BLOB y CLOB. @Temporal @Temporal(TemporalType.DATE) definido para el tipo java.sql.Date. @Temporal(TemporalType.TIME) definido para el tipo java.sql.Time. @Temporal(TemporalType.TIMESTAMP) definido para el tipo java.sql.Timestamp. @Transient Se marca as un atributo no ser persistido. @OneToOne Relaciones entre tablas. A la izquierda del To se entiende que es @ManyToOne esa misma clase y a la derecha la otra clase. @OneToMany @ManyToMany @JoinColumn (ManyToOne) Indica como se relacionan las dos tablas. @JoinTable (ManyToMany) @Inheritance Expresa herencia, se puede utilizar de varias formas segn la estrategia para recuperar los datos: strategy=InheritanceType.TABLE_PER_CLASS strategy=InheritanceType.JOINED (strategy=InheritanceType.SINGLE_TABLE) 31

Tabla X. Anotaciones ms utilizadas en Hibernate. Hay que tener en cuenta como hibernate recupera los elementos, para eso existen dos atributos en las anotaciones: FetchType.LAZY: recuperacin tarda. Valor por defecto para: o OneToMany o ManyToMany FetchType.EAGER: recuperacin temprana. Valor por defecto para: o OneToOne o ManyToOne

Y se pueden utilizar los mtodos para recuperarlos: session.get() hace recuperacin temprana. session.load() hace recuperacin tarda Existen muchas formas de interactuar con la base de datos por medio de Hibernate. Todas distintas en esencia aunque la mayora hacen lo mismo. Criterias: Son unos objetos que definen bsquedas condicionales contra algunos objetos. Es decir, si se esta buscando las vuelos con salida de mlaga y destino granada, en las que estas son elegidas en combos, lo ideal sera ponerlo en este tipo de bsquedas. HQL: Es un lenguaje creado para ser utilizado desde hibernate. Tiene una nomenclatura sencilla y parecida al sql pero con algunas diferencias para que se interacte con objetos y no con tablas. Query: son un tipo de bsqueda especial en hibernate, la cual se puede definir en una anotacin o ponerla directamente.

Lo que se pretende es hacer que bsqueda sea lo ms fcil posible de crear y de entender, pero no queremos confundir al lector, con los tres tipos de bsqueda se puede hacer las mismas bsquedas.

3.2. JSF 2
JSF 2 es un frameworks web que facilita la construccin de aplicaciones web. JSF 2 define tres caractersticas: una arquitectura de componentes, un conjunto estndar de UI widgets, y una infraestructura de aplicacin. La arquitectura de componentes JSF define una manera comn para construir UI widgets (botones, hyperlinks, checkboxes, cajas de texto, entre otros), pero tambin establece las pautas para componentes de terceros. Estos componentes con orientados a eventos y JSF permite manejar eventos del cliente (cambiar el valor de un textbox o hacer clic en un botn). Faces puede automticamente mantener tus componentes UI en sincronizacin con los objetos JAVA que coleccionan los valores ingresados por el usuario y responder a eventos, los cuales son llamados Backing Beans. Adicionalmente, tambin tiene un sistema poderoso de navegacin y soporte completo para mltiples lenguajes. JSF 2 se ejecuta en el Server, por ejemplo una aplicacin Faces se ejecutara en un contenedor web 32

como Tomcat, Oracle Application Server o Jboss, y mostrar HTML u otras marcas en el cliente. Cuando se hace un clic en un botn, Faces ejecuta un request que es enviado desde nuestro web browser hacia el Server. Faces es responsable por trasladar ese request hacia el evento que ser procesado por nuestra lgica en el Server. Es responsable tambin de mostrar en el navegador cada UI widget que hayamos definido. Los componentes ms importantes de la especificacin son: Termino UI Component (componente de usuario o simplemente denominado componente) Descripcin Un objeto mantenido en el server, que provee funcionalidad especifica para interactuar con el usuario final. Los UI components son JavaBeans con properties, mtodos y eventos. Ellos son organizados en una vista, la cual es un rbol de componentes usualmente mostrados como una pgina. Renderer Responsable por mostrar un componente UI y traducir la entrada del usuario en un valor al interior del componente. Los Renderers pueden ser diseados para trabajar con uno o mas UI components. Validator Responsable por asegurarse que el valor ingresado por el usuario es aceptable. Uno o mas validadores pueden ser asociados con un simple UI component. Backing Beans Son JavaBeans especializados que coleccionan valores desde los UI components e implementan mtodos relacionados a los eventos de los UI components. Ellos tambin pueden almacenar referencias a UI components. Converter Convierte el valor para y desde un componente para ser mostrado. Todos los UI components pueden ser asociados con un simple converter. Events y Listeners JSF usa el modelo event/listener (tambin usado por Swing). UI components (y otros objetos) generan eventos, y los listeners pueden ser registrados para manejar estos eventos. Mensajes Informacin que es muestra de regreso al usuario. Solo ciertas partes de la aplicacin (backing beans, validators, converters) pueden generar informacin o mensajes de error que pueden ser mostrados de regreso al usuario. Navigation La habilidad para moverse de una pagina a otra. JSF tiene un sistema poderoso de navegacin que esta integrado con event listeners especializados. Tabla X. Componentes de JSF 2.

33

3.2.1.

Myfaces

Myfaces en la versin 2.0 es una implementacin de JSF 2. Slo es un estndar, define un marco de trabajo. Lo mejor es empezar con una breve introduccin de JSF y Myfaces para entender mejor Myfaces. JSF es un estndar de programacin web basado en eventos. Es decir, intenta aplicar el modelo tradicional de eventos, tan utilizados en Delphi y VisualBasic, al entorno web. JSF abre a la web el modelo tradicional de componentes. Aprovechando que debe de crear estos componentes hace que estos sean reproducibles en diferentes dispositivos no solo en el HTML tpico de un explorador web. Siendo ampliable as a PDA, mviles y otros dispositivos. El paso de transformacin de un componente JSF en el elemento resultante, que puede ser otro cualquiera pero que en este proyecto ser el HTML, se hace a partir de un proceso que se conoce como renderizado. JSF separa el renderizado del componente para poder adaptarlo a cualquier dispositivo de salida. Las principales caractersticas de JSF son: Permite modificar o incorporar componentes propios o de terceros. Permite configurar y definir externamente el flujo de navegacin entre las pantallas. Aporta un ciclo de vida claro y estndar. Incluye validadores, eventos, Javabeans, conversores. Como mejora importante hay que incluir que myfaces 2.0 ya trae integrada la tecnologa de facelets. Ya que jsf es una tecnologa orientada a componentes y las JSP es una tecnologa orientada a generar servlets. Pero al no coincidir haba que hacer que alguien las casar. Es por lo que Facelets, una tecnologa orientada a construir rboles de componentes en JSF era tan habitual en los proyectos y por lo que ha sido incluida como estndar en Myfaces2.0. El ciclo de vida de JSF es el siguiente:

34

Figura X. Ciclo de vida de JSF 2. [47] Entrando en ms detalle: Restore View :El servidor recibe una llamada y recompone los objetos de la vista en el servidor. Su principal objetivo es encontrar que vista esta asociada a la peticin hecha por el usuario. Examina si FacesContext tiene un UIViewRoot para asignarle un locale y para recoger los valuebinding y asociarlo con el setValue(). Si la peticin es por get y no contiene parmetros por la url puede pasar al ltimo paso del ciclo de vida, si lo necesita pasar al siguiente. Apply Request Values: Deja que los componentes actualicen los valores que le vienen por la request. Se llama al mtodo processDecodes de todos los componentes. Process validations: Se procesan las validaciones llamando a processValidators. Update Model Values: Ahora que estn los datos y son vlidos se llaman a los mtodos que modifican los valores del modelo. Esto se produce recursivamente en el mtodo processUpdates. Invoke Application: La actualizacin del modelo ha sido completada, se llama al mtodo processApplication de UIViewRoot. Se llama a todos los eventos encolaos con phaseId.INVOKE_APPLICATION. Render Response: Se renderiza la respuesta al cliente. Se invoca al mtodo encode de cada componente del rbol de renderizado.

Los listeners son clases que se instancia entre los diferentes ciclos de vida de JSF2. Se declaran de la siguiente forma: 35

<lifecycle> <phase-listener>org.archetypeUma.listener.selection.PruebaPhaseListener</phase-listener> </lifecycle> El fichero de configuracin de myfaces es faces-config.xml, aunque se puede cambiar el nombre no es necesario. En el se pueden incluir las configuraciones de: Managed Beans o Backend Beans: es un bean como los de spring que ser instanciado desde un componente de JSF. Estas clases deben de tener las propiedades y mtodos que sean necesaria para cumplir las necesidades del componente desde el que este siendo llamado. Bundles: Declara los ficheros de internacionalizacin de la aplicacin. Deben de estar en el classpath de la aplicacin y ser declarados con el mismo nombre aqu. El idioma lo coger directamente del idioma en el que este instalado el navegador. Validadores propios: Son validadores del formulario. Se crear una clase para este fin y luego se aprovechara por toda la aplicacin. Conversores propios: Se puede disponer de conversores en algunos componentes para que muestren determinado texto de otra forma dependiendo de algn valor. Es muy utilizado en tema de horas, fechas y cosas por el estilo. Reglas de navegacin: Permite crear unas reglas de navegacin a partir de una determinada salida del Managed Bean. Es mejor verlo con un ejemplo: Componentes propios:

El servlet de myfaces guarda toda la informacin relacionada con la peticin en un objeto llamado FacesContest. Las principales caractersticas de este objeto son: Encapsula los posibles mensajes. Permite acceder al singleton de la aplicacin. Encapsula al elemento raz de la aplicacin. Contiene toda la informacin relativa al estado de la llamada y la renderizacin de la respuesta. Solo debe de existir durante la llamada y hasta que se invoque a su mtodo release. Encapsula ResponseWriter, salida de caracteres, y RespondeStream, salida binaria, como flujos de escritura para los renderizadores. Permite acceder al entorno de informacin por medio del ExternalContext. Si lo que se necesita es crear un componente propio. Hay 3 pasos mnimos que hay que seguir: Declara el componente: Lleva la lgica del componente. Debe de heredar de la clase UIComponentBase. Hay que asignarle el renderer y el tag. Los mtodos ms importantes son: o setRenderType: en el constructor para asignar el render. o getFamily: devuelve el tipo del componte. o object getBean: devuelve el objeto para obtener los valores a pintar. o restoreState y saveState: mantienen los valores al recomponer el rbol de componentes. 36

o processUpdates: Actualizacin del BackBean. Declarar el tag: Extiende de UIComponentTag. Los mtodos ms importantes que hay que implementar son: o getComponentType: tipo de componente. o getRendererType: tipo de render que lo pinta. Declarar el render: Recupera los parmetros de la request y se los pasa al componente. Existe la posibilidad de tener distintos RenderKits en funcin de la salida. Debe de heredar de la clase Renderer. Los mtodos ms importantes que debe de implementar al heredar de esta clase son: o decode: extrae los parmetros de la request. o EncodeBegin, encodeEnd, encodeChildren: pintan las etiquetas inicial, final y anidadas, respectivamente.

3.2.2.

Tomahawk

Tomahawk es una librera de componentes para JSF 2. Esta basado en Tomahwh 1.2 la galera de componentes para la versin 1.2 de JSF. Para utilizar cualquier componente de Tomahawk basta con declarar en la cabecera de la pgina que se va a utilizar Tomahawk y meter la etiqueta XML que se desee. En la cabecera de la pgina: xmlns:t=http://myfaces.apache.org/tomahawk Utilizacin de un componente de Tomahawk: <t:dataTable id="users" var="user" value="#{userListAction.users}" sortColumn="nick" sortAscending="true" styleClass="list" headerClass="datatableHeader" columnClasses="width20,width40,width40,width20"> </t:dataTable> Este es un ejemplo de componente de Tomahawk que crea una tabla con los elementos que tenga la lista users declarada en el Action userListAction.

3.2.3.

Primefaces

Primefaces es una galera de componentes JSF 2. Ha tenido una gran aceptacin en su primera versin cuando funcionaba bajo JSF 1.2. Ahora han sido los primeros en adaptar sus componentes a JSF 2.0. Lo que les da cierta ventaja en pruebas y optimizacin que el resto de libreras de uso similar. Es desarrollado por una empresa Turca, denominada Prime Technology, que ofrece su software como cdigo abierto y software libre. Primefaces esta compuesto de 3 mdulos [21]:

37

Figura X: Divisin de los 3 mdulos de Primefaces. [21] UiComponents: es el mdulo que contiene los componentes JSF. Optimus: en este mdulo se aglutinan un conjunto de utilidades que optimizan el rendimiento del proyecto en JSF2. FacesTrace: Aporta un sistema detallado para las trazas que se pueden requerir de JSF.

Primefaces tiene definido en la librera UIComponents muchos componentes, los cuales se pueden utilizar. Por ejemplo esta el componente: <component> <component-type>org.primefaces.component.Menu</component-type> <component-class>org.primefaces.component.menu.Menu</component-class> </component> En la cabecera de cada pgina donde se quiera utilizar este componente hay que establecer que se va a utilizar esta librera de primefaces. xmlns:p="http://primefaces.prime.com.tr/ui" Ahora se puede utilizar el componente: <p:menu styleClass="menu"> <p:submenu label="Menu"> <p:menuitem value="Create User" url="/pages/users/form.html"/> <p:menuitem value="List Users" url="/pages/users/list.html"/> <p:menuitem value="Uma" url="http://www.uma.es"/> </p:submenu> </p:menu> Pintara un men parecido a este en la pgina:

Figura X. Representacin del componente Men de Primefaces. El uso es muy extenso lo mejor es que si se esta utilizando la arquitectura y se necesita algo, se abra la documentacin de Primefaces que se encuentra en los downloads de este proyecto y se obtenga la 38

documentacin que se necesite, o bien en la documentacin de Primefaces.

3.3. Spring Security


En una aplicacin web es importante que el usuario confirme quien es (autentificacin) y que dependen de algunos permisos (autorizacin). Spring Security es un framework que aporta un mecanismo de gestin de la seguridad a determinados recursos a partir de los permisos del usuario. Esta basado en programacin orientado a aspectos. Se apoya en el framework spring para crear beans que gestionan la seguridad de la aplicacin. La seguridad de la aplicacin es de obligado funcionamiento en toda aplicacin. Aunque en ocasiones no se implementa. El proyecto fue creado en sus inicios por Ben Alex y permanece fuera del proyecto Spring como aadido. Antes era conocido por Acegi Security y fue con la segunda versin cuando paso a conocerse como Spring Security. Spring comprueba todas las peticiones que se hacen sobre el servidor y comprueba que el usuario este autentificado. Si no lo esta: Se crea un objeto Authentication en el SecurityContex, un contexto especial que crea spring security el cual se en sesin del usuario. Este objeto esta compuesto de los detalles del usuario y de un conjunto de permisos. Como an no se ha identificado el usuario se crea con las credenciales con un rol especial llamado annonymous. Si esta identificado: Se comprueba que los recursos a los que esta intentando acceder no tengan permisos asociados y si los tiene se le exige al usuario que contenga el permiso. Si el usuario tiene el permiso: Se le deja continuar con la actividad que estaba realizando. Si el usuario no tienen el permiso: Se le expulsa a determinada localizacin donde se le expone que no tiene un determinado permiso. Desglosando el objeto Authentication: Principal: es el nombre del usuario. Credentials: es la contrasea del usuario o algn tipo de informacin que identifique el usuario, como el certificado digital. Authorities: Array con la lista de privilegios que tiene el usuario. Al hacer la importacin al proyecto de spring security se trae un gran nmero de libreras. Se van a definir aqu para que el lector conozca su funcionamiento: Spring-core: Contiene el ncleo de la de autentificacin y acceso a control a clases e interfaces. Spring-security-web: Contiene los filtro y la infraestructura para contener spring securtiy en un entorno web. Spring-security-config: Contiene el espacio de nombres de spring security. Esto es necesario para spring security funcione. Spring-ldap: Provee a spring security de autentificacin contra un LDAP. Spring-lcd: Se utiliza si se quiere proveer a la aplicacin de seguridad en los dominios. Spring-security-openid: da sopote para autentificacin OpenId. Spring-security-cas-client: se utiliza si la autentificacin es contra un sistema cas.

Los antiguos beans FilterChainProxy y dems han sido sustituidos por etiquetas que los crean automticamente y que Spring Security conoce. 39

An as se ha mantenido la flexibilidad de Spring y se pueden insertar los conocidos como Provider. Cada Provider permite una funcionalidad diferente para Spring security. Hay una serie de etiquetas xml que hay que conocer para saber utilizar Spring Security, se van a describir las ms frecuentes. Con la etiqueta http auto-config se puede especificar que permisos necesita para entrar en cada url. <http auto-config='true'> <intercept-url pattern="/**" access="ROLE_USER" /> </http> En el ejemplo se le obliga al usuario a tener el rol ROLE_USER para entrar en cualquier url de la aplicacin. Si no lo tiene ser enviado a la url que se designe para ser la pantalla de autentificacin. Ntese que se puede jugar con las url as se podra poner por ejemplo <http auto-config='true'> <intercept-url pattern="/**" access="ROLE_USER" /> <intercept-url pattern="/security/*" access="ROLE_ADMIN" /> </http> Slo los administradores podran entrar en la carpeta de security. Pero todos necesitan autentificarse y tener el rol de ROLE_USER. Los usuarios se pueden buscar en varios sitios. Por ejemplo puede estar en el mismo XML definido con las etiquetas: <authentication-manager> <authentication-provider> <password-encoder hash="md5"/> <user-service> <user name="jcisneros" password="12b141f35d58b8b3a46eea65e6ac179e" authorities="ROLE_ADMIN, ROLE_USER" /> <user name="ncisneros" password="d1a5e26d0558c455d386085fad77d427" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager> El usuario jcisneros tendra definido los privilegios ROLE_ADMIN y ROLE_USER mientras que el usuario ncisneros solo tendra acceso a las pginas marcadas con el privilegio ROL_USER. Con la etiqueta password-encoder se declara la codificacin que tendr las claves almacenadas. <password-encoder hash="md5"/> La aplicacin deber tener una pantalla de autentificacin si se quiere hacer que sea lo ms segura posible. Hay que tener en cuenta que un usuario que no tiene ningn rol y entra por primera vez a una aplicacin que tiene spring security como mdulo de seguridad. Tiene un privilegio de ANONYMOUSLY creado por cortesa de spring security. Por tanto, se puede jugar con ese privilegio si es necesario. <http auto-config='true'> <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 40

<intercept-url pattern="/**" access="ROLE_USER" /> <form-login login-page='/login.jsp'/> </http> En este ejemplo un usuario que entrara sin estar autentificado tendra el privilegio ANONYMOUSLY y se le enviara a la pgina de login.jsp. Por qu se le deja entrar a esta pantalla? Porque esta vez si se declara que a los usuarios se les deje entrar a la pantalla de login si tiene el privilegio ANONYMOUSLY. El usuario se logara y se le metera el privilegio ROLE_USER por lo que podra tener acceso a toda la aplicacin. Con el atributo filter a none se puede hacer que no se auditen ciertos recursos, por ejemplo: <intercept-url pattern="/css/**" filters="none"/> Todos los ficheros de estilos se quedan fuera del sistema de seguridad. Esto aporta gran velocidad a la aplicacin. Sino se estara llamando al filtro de spring security demasiadas veces para recursos que no van a aportar nada a la seguridad del sistema. Si se quiere mantener a los usuarios en la base de datos hay que declarar una conexin con la base de datos con la etiqueta jdbc-user-service: <authentication-manager> <authentication-provider> <jdbc-user-service data-source-ref="securityDataSource"/> </authentication-provider> </authentication-manager> Faltara declarar el securityDataSource al que se hace referencia, como argumento se aade el bean que declara la base de datos: <beans:bean id="securityDataSource" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <beans:property name="dataSource" ref="dataSource"/> </beans:bean> Se puede declarar una pgina como expiracin de la sesin con la etiqueta: <session-management invalid-session-url="/sessionTimeout.htm" /> Spring security provee anotaciones para declarar en los mtodos de la aplicacin, hay que insertar esta etiqueta en el fichero de configuracin de spring security para poder utilizarlas: <global-method-security secured-annotations="enabled" /> Si se quiere hacer que el mtodo salvar tenga roles de administrador es necesario: @Secured ({"ROLE_ADMIN"}) public void save(User user); Si no se quiere poner nada se mantendr el mtodo como annimo. @Secured("IS_AUTHENTICATED_ANONYMOUSLY") public List<User> getUsers(); 41

De esta forma se pueden declarar que todos los mtodos del tipo save necesiten el privilegio de ROLE_ADMIN: <global-method-security> <protect-pointcut expression="execution(* org.archetypeUma.*Service.save(..))" access="ROLE_ADMIN"/> </global-method-security> Desde el cdigo JAVA se puede acceder al usuario que crea spring security con el cdigo: Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); El objeto principal contiene el nombre, el password y los privilegios del usuario logado. Spring security recorre uno tras otro todos los filtros que tiene declarado en su configuracin. Cabe destacar que cuando pasa por ExceptionTranslationFilter, si no existe el privilegio tiene que tomar decisiones. Si se quiere cambiar estas decisiones se debe de cambiar las pginas que controlan la aplicacin. <bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter"> <property name="authenticationEntryPoint" ref="authenticationEntryPoint"/> <property name="accessDeniedHandler" ref="accessDeniedHandler"/> </bean> <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <property name="loginFormUrl" value="/login.html"/> </bean> <bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl"> <property name="errorPage" value="/403.htm"/> </bean>

3.4. Herramientas de test


Los patrones de calidad exigen varios niveles de pruebas para las aplicaciones webs. Una breve descripcin de cada una de ellas: Pruebas unitarias: para cada mtodo hay que llevar a cabo una prueba en la que se confirme que el mtodo hace para lo que se haba creado. Pruebas funcionales: La funcionalidad que debe de detener las diferentes partes de la aplicacin tienen que estar cubiertas. Pruebas de rendimiento: las aplicaciones deben de dar un rendimiento ptimo, son conocidos como test de estrs, hay que probar diferentes partes de la aplicacin buscando los cuellos de botella para que el equipo de desarrollo pueda mejorarlos.

3.4.1.

JUnit
42

Junit es un frameworks para automatizar las pruebas unitarias de aplicaciones Java. Es un software de cdigo abierto. Fue creado por Erich Gamma y Kent Beck. Consta de un conjunto de clases que el programador puede utilizar para construir sus casos de prueba y ejecutarlos automticamente. Los casos de prueba son realmente programas Java. Quedan archivados y pueden ser reejecutados tantas veces como sea necesario. Es adecuado para el desarrollo dirigido por las pruebas. Test-driven develoment, tecnologa planteada hace poco aos que sostiene que no hay que programar y luego hacer un test que lo pruebe, sino que hay que hacer un test que tenga las entradas y las salidas que se deseen y luego implementar el cdigo que se necesite para solucionarlo. Los test de Junit se ejecutan como una clase Java normal, aunque tienen una clase de inyecciones y anotaciones que lo hacen un poco especial. Por lo tanto la mejor manera de ejecutar estos test es por medio de otra aplicacin que sea capaz de interpretarlos de la mejor manera. La forma ms utilizada es por maven, ant o por algn IDE que ya tenga bien integradas las pruebas unitarias dentro de sus caractersticas. Junit proporciona una Api para la ejecucin de los test. Tiene una serie de clases y objetos que facilitan el testeo. Todos los test en Junit tienen que llevar la anotacin: @RunWith(SpringJUnit4ClassRunner.class) Esta anotacin expresa que vamos a realizar un test en Junit utilizando Spring. La siguiente anotacin: @ContextConfiguration(locations = { "classpath:/spring/applicationContext-resources.xml", "classpath:/spring/applicationContext-dao.xml", "classpath:/spring/applicationContext-service.xml" }) Se usa para especificar el contexto de Spring que es necesario para que el test se ejecute correctamente. Cada mtodo que sirva de test de otro mtodo de la aplicacin hay que catalogarlos con la anotacin @Test

3.4.2.

JMock

JMock es una API para las pruebas unitarias de sistema en Java. Utiliza Junit para algunas operaciones. JMock permite la creacin de test unitarios exhibiendo determinados componentes y sustituyndolos por sus 'Mocks'. Mocks es una expresin que representa una burla. Esa es la principal ventaja de los Mocks, no hace falta probar que hace un objeto que tiene el programa si se esta seguro que el programa funciona. Lo mejor es crear un objeto Mockery que sustituya a toda esa funcionalidad y que hagamos el test dependiendo de lo que devuelvan. Los test de JMock se apoyan en Junit4 por lo que hay que declarar en la cabecera la anotacin: 43

@RunWith(JMock.class) Cada test tiene que ir acompaado de la anotacin: @test Al programar una prueba en Jmock hay que tener en cuenta varios factores que son muy importantes: El nmero de invocaciones a un Mock. Mtodo oneOf exactly(n).of atLeast(n).of atMost(n).of Descripcin La invocacin ha este mtodo se ha producido una sola vez. La invocacin es esperada n veces. La invocacin es esperada hasta n veces. La invocacin es esperada al menos n veces.

between(min, max).of La invocacin se espera entre un intervalo. allowing ignoring never La invocacin es permitida algn nmero de veces pero no tiene porque suceder. Similar a la de permitir. La invocacin a este mock no se debera de producir.

Tabla X. Nmero de invocaciones a los Mock. Comprobacin de argumentos. Se comprueba que los argumentos que entran a un mtodo son los esperados: Descripcin Los argumentos son iguales que n. Los argumentos son un objeto como o. El argumento es alguna instancia del tipo que se establezca en type. El argumento es una instancia del tipo o de una subclase. El argumento es una instancia del tipo o de una subclase. El argumento es null.

Mtodo equal(n) same(o) any(Class<T> type) a(Class<T> type) an(Class<T> type) aNull(Class<T> type)

aNonNull(Class<T> type) El argumento no es null. not(m) anyOf(m1, m2, ..., mn) allOf(m1, m2, ..., mn) Los argumentos no son m. Los argumentos se encuentrar entre m1 y mn. Los argumentos son los que se encuentra entre m1 y mn.

Tabla X. Argumentos a los objetos Mock. Acciones. Se puede especificar que devuelve cada Mock, los mtodos que lo consiguen son: 44

Mtodo will(returnValue(v)) will(returnIterator(c))

Descripcin Devuelve el objeto c al ser llamado. Devuelve un nuevo Iterador sobre la coleccin c para cada invocacin.

will(returnIterator(v1, v2, ..., vn)) Devuelve un nuevo iterador para cada elemento invocacin, desde v1 hasta vn. will(throwException(e)) will(doAll(a1, a2, ..., an)) Devuelve una excepcin. Hace muchas acciones sobre una invocacin.

Tabla X. Mtodos que representan las devoluciones de objetos Mock.

3.4.3.

JMeter

Jmeter es una aplicacin standalone que prueba las aplicaciones webs por medio de peticiones HTTP. Esta escrito en Java y es cdigo abierto. Originalmente desarrollado por Stefano Mazzocchi. Jmeter puede ser utilizado para las pruebas de rendimiento o para las pruebas funcionales o para las pruebas de integracin. Jmeter soporta HTTP, JDBC, SOAP, XML-RPC, FTP, SMTP, LDAP, JUnit y ms. La forma de guardar y cargar los ficheros de pruebas es por medio de XML. Esto es una gran ventaja ya que es un formato muy utilizado en el sector de la informtica y puede ser manipulado con facilidad. Jmeter tiene un sistema de documentacin capaz de mostrar grficas para los rendimientos de la cpu, de la memoria, del recolector de basura de Java, del los hilos utilizado y del uso de las conexiones. Trabajando con esta herramienta es fcil encontrar cuellos de botella. La estructura de carpetas del proyecto Jmeter una vez instalado en el equipo quedara de la siguiente manera: bin contiene los .bat y .sh ficheros para arrancar Jmeter. Tambin contiene ApacheJMeter.jar y otras ficheros de propiedades. docs este directorio contiene la documentacin de JMeter. extras ficheros extras del constructor ANT lib contiene las libreras que necesita JMeter. src contiene subdirectorios por cada protocolo y componente. test directorio de test. xdocs XML para la documentacin. Hay unos conceptos que hay que tener en cuenta para trabajar con Jmeter: Thread: Un hilo representa un usuario. Cuando se ejecuta un hilo es como si un usuario entrar en la aplicacin e hiciera una determinada prueba. Thread Group: Un grupo de hilos es un escenario de trabajo que se va a crear para unos usuarios. Es decir si un usuario entra, se registra, ejecuta una bsqueda y se sale. Se crear 45

un grupo de trabajo para ese escenario. Test plan: es uno o varios grupos de hilos. Sampler: Un sampler es algo que enva peticiones al servidor, Listener: Un listener escucha las respuestas generada por los samplers. Los listeners son utilizados para ejecutar los resultados de las peticiones al servidor. Assertion: Un assertion es utilizado para especificar que una respuesta debera de tener un determinado contenido. Hay varios tipos de assertions dependiendo de lo que se necesita y de lo que se quiera comprobar. Se puede comprobar por ejemplo que la peticin tiene como cabecera. <title>ttulo<title>. Logic Controller: aporta un mecanismo para controlar el flujo de Thread Group. Aade sentencias del tipo if-then or do- para hacer un programa lgico. Workbench: El Workbench es el rea de trabajo. Es el lugar donde JMeter ejecuta los test y crea los reporting. Timers: Introduce tiempos cronometrados en los test.

Para empezar a trabajar con JMeter hay que grabar el circuito que hace la prueba: Se crea un fichero nuevo de JMeter. Inicialmente se crean dos apartados, un Plan de pruebas y un Banco de Trabajo. En el Plan de pruebas se crea un Grupo de Hilos.

Figura X. Insercin en JMeter de un Grupo de Hilos. Se aade un Ver rbol de Resultados y Ver Resultados en rbol en el Banco de Trabajo:

46

Figura X. Insercin en JMeter de un Ver Resultados en rbol. Segundo probamos el circuito desde Jmeter. Hay que darle al botn Lanzar y ejecutar el test. Tercero integramos un plugin de JMeter en Maven para que cuando ejecute la fase del ciclo de vida de test se ejecuten los test de JMeter. Pero este plugin an esta en fase de desarrollo, se ha probado en este proyecto y no ha funcionado correctamente. Ser suficiente con probar el test en JMeter aunque no este presente en el ciclo de vida de Maven.

3.5. Spring Framework


Spring es un framework de software libre para el desarrollo de aplicaciones. Nace en el J2EE Design & Development de Rod Johnson. Su primera versin es del 2003 escrita por el mismo Rod Johnson con licencia Apache 2.0. El framework se ha popularizado por sus fciles soluciones a problemas complejos como la transaccionalidad, los aspectos y la inversin de control. Una de las traducciones de Spring es engranage y esa es la principal utilidad de Spring intenta unir los diferentes frameworks que se utilizan en una aplicacin. En las ltimas versiones Spring se ha aprovechado de las anotaciones para quitarse de encima tanta configuracin en XML como tena acostumbrado. Sobre todo con la llegada de la versin 3 a finales del 2009. Spring ha sido muy apoyado por la comunidad de programadores de software libre por lo que ha sido ampliado a gran velocidad abarcando una gran cantidad de reas. Hay que destacar en este proyecto Spring Security ya que se va a utilizar como capa de seguridad en la arquitectura. Spring facilita el Test Driven Development y los EJB. Con la librera spring-test se puede utilizar las funcionalidades de las libreras JUnit y JMock. Esto se explica ms en profundidad en sus apartados. Spring brinda soporte a las siguientes tecnologas de persistencia de objetos: DAO 47

JDBC ORM Hbenate JDO Oracle TolLink iBatis SQL Maps JPA

Spring es un conjunto de libreras que se pueden dividir en 6 mdulos [51]: Spring Core: Es la parte fundamental del framework. Proporciona funcionalidades de inyeccin de dependencias y de gestin como contenedor de beans, as como un patrn de acceso a beans estilo factora. El contenedor gestiona las instancias de los beans configurados en el framework. Spring Context: Suministra la manera de acceder a los beans, es decir, las diversas formas para cargar el contexto de la aplicacin, principalmente a travs del contenedor de servlets, declarando el contexto de la aplicacin en el fichero web.xml. Spring DAO: Se basa en el patrn de diseo DAO, el cual proporciona una capa de abstraccin JDBC, gracias a la cual se produce un ahorro de tiempo y un cdigo mucho ms sencillo de mantener y eficiente, ya que no es necesario teclear el cdigo JDBC para establecer una conexin en todos y cada uno de los accesos a la base de datos. Spring AOP: Este mdulo proporciona servicios empresariales de manera declarativa, especialmente, como reemplazo para los servicios declarativos de EJB. El ms importante de dichos servicios es el manejo declarativo de transacciones, que est construido sobre la abstraccin de transacciones spring. Spring ORM: El mdulo ORM proporciona el soporte para la integracin con otros frameworks de mapeo objeto-relacional, incluyendo Hibernate. Spring web: Provee caractersticas bsicas de integracin orientadas a la web. Inicializacin de contextos mediante ServletsListeners y un contexto de aplicacin orientado a web.

48

Figura X. Esquema de los mdulos de Spring. [49] En la comunicacin entre diferentes capas de la aplicacin no se irn creando ni destruyendo objetos. Sino que se irn creando beans de spring que sern manejados por Spring haciendo el trabajo ms sencillo. Los beans de Spring son objetos que forman parte de la aplicacin y que son instanciados, configurados y gestionados por el contenedor. Los beans y sus dependencias estn configurados en los metadatos del contenedor, en un xml de configuracin o con anotaciones. La interfaz que gestiona los beans es BeanFactory. Interfaz que provee los mecanismos de configuracin necesarios para gestionar cualquier tipo de objeto. Es el contenedor IoC (creacin, configuracin, ensamblado) XmlBeanFactory es la implementacin tpica, ya que provee los beans desde un XML. La clase que gestiona los beans es: Es una extensin de BeanFactory. Provee funcionalidades para integrarse fcilmente con otras capas, como AOP, i18n, web... El scope es una caracterstica que tiene el bean de Spring, hay diferentes formas de crear el bean segn el scope. Los diferentes tipos son: singleton: una sola instancia por contenedor IoC de Spring (es el valor por defecto). prototype: una instancia nueva cada vez que se pide el objeto al contenedor IoC de Spring. request: una instancia por peticin HTTP. Slo es vlido para un Application que sabe que es Web 49

session: una instancia por sesin HTTP. Slo es vlido para un Application que sabe que es Web global session: una instancia por sesin HTTP global(portlets). Slo es vlido para un ApplicationContext que sabe que es Web.

Definicin del datasource mediante Spring: El datasource es una interfaz que se encuentra en el paquete javax.sql.DataSource de J2SDK, la cual se emplea como factora de objetos Connection. En algunos proyectos de JAVA, sobre todo en los ms antiguos, se utilizaba una conexin con la base de datos cada vez que se haca una operacin. Esto obligaba a declarar el driver, abrir la conexin y luego cerrarla. Spring permite la declaracin del datasource de varias maneras. Entre ellas estn las conexiones JNDI, con ficheros .properties, o con Apache Jakarta Commons DBCP. Todas estas pueden ser declaradas en los ficheros de contexto de Spring. Spring incorpora un conjunto de anotaciones para definir e inyectar los beans. Las que ms se van a utilizar son [52]: @Repository: Esta es una anotacin de Spring. Estamos indicando que esta es una clase relacionada con la capa de persistencia, y que debe ser un Singleton (slo habr una instancia de la clase), y todos los Threads de la aplicacin la compartirn). @Autowired: Esta es una anotacin de Spring. Sirve para indicarle a Spring que cuando vaya a crear la instancia debe "inyectarle" (pasarle) en el constructor una referencia. @Transactional: Esta es una anotacin de Spring. Estamos indicando que el mtodo en cuestin es transaccional. Lo que har Spring es comprobar si ya existe una transaccin abierta, si existe se unir a ella, y si no existe, abrir una nueva transaccin (este comportamiento es configurable). De esta forma se asegura que toda operacin de la base de datos se realiza dentro de una transaccin. Adems si durante la ejecucin del mtodo se produce alguna excepcin de Runtime, se har automticamente rollback de la transaccin (este comportamiento tambin es configurable). @Service: Esta es una anotacin de Spring, similar a @Repository que ya habamos visto antes. Estamos indicando que esta es una clase relacionada con la capa de servicio (clases de negocio), y que debe ser un Singleton. @Resoruce: Esta anotacin es del estndar, por lo que es vlida tanto con Spring como con EJB3.0. Esta indicando que al crear la instancia de esta clase se debe "inyectar" (inicializar) en este atributo una referencia a la instancia del Dao (es la instancia que habamos declarado anteriormente con @Repository). @Required: Obliga a fijar la propiedad en tiempo de configuracin. Solo es aplicable en los setters. @Scope: puede establecerle un determinado scope a una propiedad. @Component: es una anotacin genrica.

Se puede acceder directamente al contenedor de beans declarados en un xml obteniendo directamente los beans, no hara falta el arranque del contexto. Esto puede ser til por ejemplo en los test. Se obtiene el contexto de Spring: ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.service.xml", 50

applicationContext-dao.xml}); Se saca el bean del contexto de spring: IUserService service = context.getBean("userService", UserServiceImpl.class); Se utiliza normalmente: List<User> listado service.getUsers();

3.6. Log4j
Log4j es una API para la monitorizacin de trazas en el cdigo Java. En sus inicios los programadores en Java escriban en la salida estndar por medio de Sytem.out.println(arg). Esto era muy poco flexible ya que los programadores exigan poder escribir de determinadas formas y en diferentes sitios. Fue entonces cuando log4j se empez a incluir en todos los proyectos como la librera que gestionaba las trazas. Log4j proporciona unas interfaces que hacen que se pueda llamar desde cualquier punto del proyecto y que tiene como misin escribir en la salida que tenga definida en el fichero log4j.xml o log4j.properties segn la versin que se este utilizando. Dos partes significativas de log4j son los appenders y los layouts. Appenders: sirven para definir que hay que hacer con la informacin, donde hay que escribirla. Layouts: sirve para definir la informacin que acompaara a cada nueva lnea de traza y para darle formato. Se pueden definir diferentes formatos de layouts, si por ejemplo tenemos una salida para fichero y otra para que envi un email se puede definir una para cada. Log4j proporciona diferentes niveles de trazas segn sus mtodos: public void debug(Object message); Es el nivel ms bajo, debe de ser utilizado por los programadores en la fase de desarrollo y pruebas. public void info(Object message); Es un nivel medio en el que se intenta dejar constancia a los lectores de las trazas que el evento que acaba de ocurrir en el programa es significativo. public void warn(Object message); Es en nivel alto en el que se advierte que no se debera estar produciendo el evento. public void error(Object message); Es un nivel alto que formaliza un error que no se debera de haber producido en la aplicacin. Ntese que no se debera de haber producido. Si es un error controlado lo mejor es bajar a un nivel ms bajo. public void fatal(Object message); El nivel ms alto, si ha ocurrido esta clase de error en probable que algn sistema deje de funcionar dentro de la aplicacin.

Es importante en produccin que el nivel de traza este lo ms alto posible. Ya que la entrada-salida en un servidor esta muy penalizada y hace que se ralentice el rendimiento de la aplicacin. En el caso de estudio, se habrn declarado dos appenders. Uno para la salida estndar, normalmente 51

la pantalla, y otro para fichero. Naturamente lo mejor es dejar el fichero para los sistemas en producin o similar y la pantalla para los equipos de desarrollo. Las trazas por defecto estn a nivel de error, definidos en: <root> <level value="ERROR"/> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> Pero los paquetes org.hibnate y org.apache estn a INFO. Se han puesto como ejemplo de los diferentes niveles de trazas que se pueden hacer con log4j. <logger name="org.hibernate"> <level value="INFO"/> </logger> <logger name="org.apache"> <level value="INFO"/> </logger> Solo falta aadirlo a la clase Java que quiera imprimir algo en los logs. Esto se hace con la declaracin de los imports en la cabecera: import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; Crear la variable de clase protected final Log log = LogFactory .getLog(this.getClass()); y con el siguiente cdigo en el mtodo: log.error(mensaje);

52

53

4. Definicin de la arquitectura
Las caracteristicas principales de la arquitectura se han intentado solucionar con diferentes frameworks: Trazabilidad: Log4j Validaciones: Myfaces 2 Internacionalizacin: Myfaces 2 Threads: Spring 3 Myfaces 2 Transaccionalidad: Spring 3 Seguridad: Spring Security 3 Sesin: J2SE Excepciones: J2SE Pool: Conexiones BD: Spring 3 - Pool-DBCP Cache: OSCache+hibernate 3 Plantillas: Faceslets en myfaces 2.0 Componentes JSF2: Primefaces2 y Tomahawh2 ORM: Hibernate 3

Estos frameworks se han definido anteriormente y se han integrado dentro de la arquitectura. La arquitectura se entrega totalmente operativa para empezar los nuevos proyectos. Al explicar esta arquitectura es inevitable empezar a hablar por el patrn MVC. Se trata de dar una solucin mediante el patrn MVC pero adecundolo a los frameworks y herramientas que existen en la actualidad. Esquema general de la arquitectura:

54

Figura X. Esquema general de la arquitectura. El esquema de la arquitectura se puede ver como una estructura de capas que se comunican entre si para aportar algo a la capa superior, algo de lo que la capa superior no quiere entender y que la capa inferior le soluciona.. La divisin es la siguiente: Model: se encarga de almacenar los POJOs y Beans de la aplicacin. Corresponde con el modelo de datos. Controlador: Esta capa se dividir al mismo tiempo en otras tres capas: o Actions: Se utiliza para para intercambiar valores en la request o en la sesin, pero no tendr lgica de negocio. o Services: Tendr la lgica de negocio pero no acceder directamente a ninguna fuente de datos. o DAO: Se utilizar para acceder a las fuentes de datos. Vista: Guarda las pginas y los recursos estticos que necesitan las pginas. El comportamiento de las capas es apreciado fcilmente en un diagrama de comportamientos, se puede ver como las llamadas a la capa inferior y espera de la respuesta:

55

Figura X. Diagrama de comportamientos de la arquitectura. Explicacin del comportamiento: 1. El usuario esta en su navegador web y hace una peticin http mediante la pulsacin de un botn o un enlace. 2. El Servlet de Myfaces recoge las peticiones y si tiene permisos mediante Spring Security evala la peticin y llama a los Actions si son necesarios. 3. Los Actions pueden resolver las peticiones que le hay si le haga el servlet de Myfaces. Si al Action le falta alguna lgica de negocio se la lo pide a la capa Service que le ejecute el cdigo necesario. 4. Si el Action ha invocado a algn mtodo de la capa Service este se ejecutara y si le hace falta recuperar o hacer alguna modificacin en el modelo de datos se lo pedira a la capa DAO. 5. Si la capa Service ha invocado a algn mtodo de la capa DAO, esta capa trata de resolver la peticin y devolverle a la capa Services lo que le esta pidiendo. Estas capas hay que meterla en un proyecto JAVA con Maven, por lo que hay que organizarlo de forma que sea lo ms simple posible y que cumpla con todos las necesidades de la arquitectura. Maven necesita que las capas se siten en JAR o WAR para que se acoplen bien en un proyecto y se pueda modificar con facilidad. De esta manera se han creado dos mdulos en dos JAR (model y core) y un mdulo en un WAR (web).

56

Web Actions Fomularios Pages Recuros estticos Core Services DAO Utilidades Model POJOs Beans

WAR

JAR

JAR

Figura X. Representacin de los paquetes generados por el arquetipo. Qu ventaja aade separar la arquitectura en una capa Model, Core y Web? Las aplicaciones webs en Java han tomado caminos muy dispersos con las llegadas de los frameworks. Cada proyecto puede estar con un framework distinto o puede que llegue el momento en un proyecto de migrar de algn tipo de framework a otro. Dividiendo la arquitectura en la lgica de negocio y en la lgica de gestin de una aplicacin web se abstrae el framework utilizado y se aprovecha otras ventajas. La creacin de las capas se va a llevar a cabo de clases JAVA, con ciertas particularidades ya que hay que seguir ciertos patrones de diseo. Para crear cada clase en una capa DAO o Services hay que crear una interfaz y una implementacin. Las capas se expondrn de abajo a arriba, desde la capa ms baja (base de datos) hasta la ms alta (vista de la pgina).

4.1. Capa Model


El modelo se va a encapsular en el paquete model del proyecto. Son necesarias las dependencias de hibernate como ORM entre la aplicacin y la base de datos. Tambin es necesario un sistema de gestin de trazas como log4j. Cada objeto del nuevo proyecto que se vaya a crear con la arquitectura deber de heredar de BaseObject.java, un objeto abstracto que impondr un comportamiento comn a todos los POJO's. BaseObject.java package org.archetypeUma.model.pojos; public abstract class BaseObject { 57

public abstract String toString(); public abstract boolean equals(Object o); public abstract int hashCode(); } Son mtodos que suelen utilizar los frameworks obligatoriamente y que hay que obligar a los programadores a implementarlos. Hay algunas reglas que hay que exigir a la hora de crear los POJOS: Cada objeto tiene que tener un identificador nico. Este identificador tiene que ser distinto que la clave candidata. Ser creado como una secuencia o como un valor incremental, dependiendo de la base de datos. En el mtodo equal y hashCode se utilizar la clave candidata y no la clave primaria. La base de datos debe de estar normalizada, sin excepciones. Los constructores vacos estarn protegidos, solo Hibernate gestionar la creacin de objetos. Las variables sern declaradas como private y les acompaar su getters y su setters.

4.2. Capa Core


En esta capa se incluyen las clases que hacen la lgica de negocio de la aplicacin y los accesos a la base de datos o a cualquier otra fuente de datos. Dentro de la capa core, hay que diferenciar la capa DAO y la capa Services. Spring define los beans en XML, en este caso se declararn mediante anotaciones, por lo tanto hay que sealarle a Spring donde estn las clases que van a tener anotaciones que creen beans. Esto se hace para cada una de las capas. En el fichero applicationContext-dao.xml se declaran los beans de la capa dao y en applicationContext-service.xml se declaran los beans de la capa services. Cada uno de estos xml contienen la referencia a donde estn los beans que tienen que crear, esto se le marca con la etiqueta context:component-scan. Seala en que clases estn declarados sus beans. 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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-lazy-init="true"> <description>Beans DAO</description> <context:annotation-config/> <context:component-scan base-package="org.archetypeUma.dao.implementation"/> 58

</beans> 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:aop="http://www.springframework.org/schema/aop" 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-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" default-lazy-init="true"> <description>Beans Services</description> <context:annotation-config/> <context:component-scan base-package="org.archetypeUma.service.implementation"/> </beans> Los beans de la capa DAO se marcarn con la etiqueta @Repository("userDao") con el nombre que se le quiera dar al bean. Los beans de la capa service se marcarn con la etiqueta @Service(value="userManager") junto al nombre del bean. Para inyectar la capa de DAO en la capa services, hay que hacer una referencia con @Qualifier acompaada siempre de la anotacin @Autowired. Declaracin del dao de usuario en el services de usuario: @Autowired @Qualifier("userDao") private IUserDao userDao = null; Si se quiere inyectar un bean de spring correctamente siempre debe de ir acompaado de su setter: public void setUserDao(IUserDao userDao) { this.userDao = userDao; }

4.2.1.

Capa DAO

La capa DAO (Data Access Object) es la capa encargada del acceso a los datos. Como en principio la nica forma de acceso a datos que existe es la base de datos, solamente aparece en el arquetipo 59

los DAO de acceso a base de datos. Si hubiera cualquier otro acceso a datos que se quiera incluir en la aplicacin habra que situarlo en esta capa. En la capa DAO todas las interfaces heredarn de la interfaz IBaseDao y las implementaciones heredan de BaseDaoImpl ya que todas tienen unos mtodos comunes, se metern para mayor eficiencia en esta clase. IBaseDao.java package org.archetypeUma.dao.interfaces; import java.io.Serializable; import java.util.List; public interface IBaseDao<T, PK extends Serializable> { List<T> getAll(); T merge(T object); T get(PK id); } BaseDaoImpl.java package org.archetypeUma.dao.implementation; import java.io.Serializable; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.archetypeUma.dao.interfaces.IBaseDao; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class BaseDaoImpl<T, PK extends Serializable> extends HibernateDaoSupport implements IBaseDao<T, PK> { protected final Log log = LogFactory.getLog(this.getClass()); @Autowired protected SessionFactory sessionFactory = null; private final Class<T> persistentClass; public BaseDaoImpl(SessionFactory sessionFactory, final Class<T> persistentClassP) { setSessionFactory(sessionFactory); this.persistentClass = persistentClassP; } public Class<T> getPersistentClass() { return persistentClass; } public final List<T> getAll() { List<T> result = null; 60

result = getHibernateTemplate().loadAll(persistentClass); return result; } public final T merge(T object) { T result = null; result = (T) super.getHibernateTemplate().merge(object); return result; } public final T get(final PK id) { final T entity = (T) super.getHibernateTemplate().get( this.persistentClass, id); return entity; } } Hay que crear una interfaz y una implementacin de esa interfaz para cada POJO que exista en la aplicacin. Por lo tanto, como tenemos una tabla TABLE_USER necesitamos un POJO que sea la conversin a cdigo JAVA (User.java) y una interfaz e implementacin de la capa DAO (IUserDao.java y UserDaoImpl.java).

4.2.2.

Capa Services

La capa Service agrupa los mtodos de la aplicacin que solucionan la lgica de negocio. Hay que crear una nuevo elemento en la capa cuando haga falta un nuevo grupo funcional, es decir, en el arquetipo hay un grupo funcional que gestiona un mantenimiento de usuarios, entonces hay que crear un IUserManager.java para implementar la lgica que requiere listar, crear, eliminar, modificar usuarios. Sin embargo no ha sido necesario crear un ICityManager porque aunque es necesario listar y utilizar las ciudades, esto se ha realizado en un mantenimiento de usuarios y hay que localizarlo en el manager creado con ese propsito IUserManager.java La transaccionalidad se produce en la capa Services, se lleva a cabo mediante la utilizacin de programacin orientada a aspectos y es controlada por las anotaciones de Spring. Se define en el fichero: applicationContext-transactional.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:aop="http://www.springframework.org/schema/aop" 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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" default-lazy-init="true"> 61

<!-- AOP: Configuration and Aspects --> <aop:config> <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..service.*Manager.*(..))" order="2" /> </aop:config> <!-- Enable @Transactional support --> <tx:annotation-driven transaction-manager="transactionManager" /> <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf" dependency-check="none" lazy-init="false"> <property name="transactionManager" ref="transactionManager" /> </bean> <!-- Enable @AspectJ support --> <aop:aspectj-autoproxy proxy-target-class="false" /> <!-- Enable @Configured support --> <aop:spring-configured /> <tx:advice id="txAdvice"> <tx:attributes> <!-- Read-only commented out to make things easier for end-users --> <tx:method name="get*" read-only="true"/> <tx:method name="*" /> </tx:attributes> </tx:advice> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </beans> Se fuerza a todos los mtodos que empiecen por get a ser de solo lectura. El resto de mtodos de la aplicacin podrn ser transaccionales o no dependiendo de las anotaciones con las que sea marcada. Como ejemplo podemos utilizar a IUserManager.java que ha sido marcada como de solo lectura. @Transactional(readOnly = true) public interface IUserManager { Sin embarbo el mtodo de la misma clase 'save' ha sido marcado como transaccional pero transaccional . @Transactional(readOnly = false) User save(User user, Long idCity);

4.3.

Capa Web

En esta capa se incluye las pginas y las clases que interactan entre el servidor y el navegador en una aplicacin web.

62

4.3.1.

Capa Vista

Como vista se entienden las pginas HTML, las pginas jsf y los recursos estticos que se necesiten. Los ficheros estticos deben de estar contenidos en la carpeta /web/src/main/webapp/resources quedando de forma estndar 3 posibilidades: css: aqu se depositarn las hojas de estilos necesarias para que la aplicacin web se procese correctamente en cada servidor. js: son los ficheros de javascripts o algn otro lenguaje de scripts que se quiera utilizar desde las pginas jsf. images: son las imgenes que se van a utilizar en la pgina web, puede ser de cualquier tipo gif, png, bmp. Las plantillas jsf tambin conocidas como templates se guardarn en la carpeta /web/src/main/webapp/templates/ donde ya hay un ejemplo de una plantilla funcionando y que puede servir como base. Todas las pginas que hereden de este template tendrn la misma apariencia y funcionalidad. En estas plantillas ya se ponen las hojas de estilos, men, cabeceras y pie de pginas para que cada pgina quede lo ms simple posible. La internacionalizacin nos va ha permitir mostrar la aplicacin segn el idioma del usuario. Para ello en el fichero faces-config.xml hay que especificar que localizaciones soporta la aplicacin, y cual es la localizacin por defecto: faces-config.xml <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/webfacesconfig_2_0.xsd" version="2.0"> <application> <variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> <resource-bundle> <base-name>i18n</base-name> <var>i18n</var> </resource-bundle> <message-bundle>i18n</message-bundle> <locale-config> <default-locale>es</default-locale> <supported-locale>es</supported-locale> <supported-locale>en</supported-locale> </locale-config> </application> </faces-config> Utilizar la internacionalizacin es muy sencillo, solo hay que invocar al Bean que tiene la internacionalizacin: 63

<h:outputText value="#{i18n['users']}" /> Llamar a la propiedad deseada que hay que previamente escribir en el fichero i18n.properties. i18n.properties: # Latin1 JAVA # \u00c1 # \u00c9 # \u00cd # \u00d3 # \u00da # \u00d1 # Space \u2008 add=Add update=Update remove=Remove title=ArchetypeUma users=Users userEdit.nick=Nick userEdit.name=Name userEdit.city=City userEdit.image=Image userEdit.title=User edit login=Login login.nick=Nick login.password=Password login.title=Login required=is required button.done=OK button.back=Back button.cancel=Cancel footer.uma=Universidad de M\u00e1laga footer.informatica.uma=Escuela T\u00e9cnica Superior de Ingenier\u00eda Inform\u00e1tica Hay que tener en cuenta que los acentos y las letras especiales hay que traducirlas al cdigo que JAVA entiende. Se crea un template por defecto que ser actualizado llegado el momento de arrancar el proyecto ya que ahora mismo es muy bsico: template.xhtml <f:view contentType="text/html"> <h:head> 64 Latin1 JAVA \u00e1 \u00e9 \u00ed \u00f3 \u00fa \u00f1

<title><h:outputText value="#{i18n['title']}" /></title> <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/a> <ui:insert name="head"></ui:insert> <h:outputStylesheet name="styles.css" library="css"/> <h:outputStylesheet name="skin.css" library="css"/> </h:head> <h:body syleClass="body"> <t:div id="column1" styleClass="column1"><br/></t:div> <t:div id="column2" styleClass="column2"> <ui:include src="/common/header.xhtml" /> <t:div id="page" styleClass="page"> <t:div id="content" styleClass="content"> <ui:insert name="content"></ui:insert> </t:div> </t:div> <ui:include src="/common/footer.xhtml" /> </t:div> <t:div id="column3" styleClass="column3"><br/></t:div> </h:body> </f:view> Todas las pginas definidas en Myfaces podran heredar de este template si se pretende que todas las pginas tengan el mismo aspecto. Las pginas se encuentran en la carpeta \web\src\main\webapp\pages\ y se crea una nueva carpeta por cada grupo funcional que se necesite. El ejemplo esta para hecho para los usuarios. Se ha creado la carpeta user y dentro estn todas las pginas que se han necesitado para su mantenimiento.

4.3.2.

Capa Action

Los Actions son las clases JAVA que responden a los eventos JSF. Los Actions no utilizarn el patrn Facade, ya que Myfaces controla su ciclo de vida y no hay que interferir. En el fichero faces-config.xml se puede definir los Actions, componentes, listeners y dems elementos de JSF. Ahora mismo solo esta definido los ficheros de la internacionalizacin. Es esta arquitectura todos los Actions deben de heredar de la clase BaseAction. Esta clase no es intrusiva en el comportamiento de JSF, pero si es conveniente utilizarla ya que concentra unos mtodos que se reutilizan mucho en esta capa. package org.archetypeUma.actions; import java.text.MessageFormat; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.ResourceBundle; import javax.faces.context.FacesContext; import javax.servlet.ServletContext; 65

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.collections.comparators.NullComparator; import org.apache.commons.collections.comparators.ReverseComparator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Default Action. */ public class BaseAction { /** * constants */ public static final String JSF_PAGE_EXTENSION = ".xhtml"; public static final String JSF_URL_EXTENSION = ".html"; /** * log. */ protected final Log // Convenience methods public FacesContext getFacesContext() { return FacesContext.getCurrentInstance(); } public String getParameter(final String name) { return getRequest().getParameter(name); } public String getBundleName() { return getFacesContext().getApplication().getMessageBundle(); } public ResourceBundle getBundle() { final ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); return ResourceBundle.getBundle(getBundleName(), getRequest() .getLocale(), classLoader); } public String getText(final String key) { String message; try { 66

log

= LogFactory.getLog(this .getClass());

message = getBundle().getString(key); } catch (final java.util.MissingResourceException mre) { log.warn("Missing key for '" + key + "'"); return "???" + key + "???"; } return message; } public String getText(final String key, final Object arg) { if (arg == null) { return this.getText(key); } final MessageFormat form = new MessageFormat(getBundle().getString(key)); if (arg instanceof String) { return form.format(new Object[] { arg }); } else if (arg instanceof Object[]) { return form.format(arg); } else { log.error("arg '" + arg + "' not String or Object[]"); return ""; } } /** * Servlet API Convenience method * * @return HttpServletRequest from the FacesContext */ protected HttpServletRequest getRequest() { return (HttpServletRequest) getFacesContext().getExternalContext() .getRequest(); } /** * Servlet API Convenience method * * @return String from the FacesContext */ protected String getRequestParam(final String param) { String result = null; result = getFacesContext().getExternalContext() .getRequestParameterMap().get(param); return result; } /** 67

* Servlet API Convenience method * * @return the current user's session */ protected HttpSession getSession() { return getRequest().getSession(); } /** * Servlet API Convenience method * * @return HttpServletResponse from the FacesContext */ protected HttpServletResponse getResponse() { return (HttpServletResponse) getFacesContext().getExternalContext() .getResponse(); } /** * Servlet API Convenience method * * @return the ServletContext form the FacesContext */ protected ServletContext getServletContext() { return (ServletContext) getFacesContext().getExternalContext() .getContext(); } /** * Sort list according to which column has been clicked on. * * @param list * the java.util.List to sort * @return ordered list */ protected List sort(final List list, String sortColumn, boolean ascending) { boolean nullsAreHigh = false; Comparator comparator = new BeanComparator(sortColumn, new NullComparator(nullsAreHigh)); if (!ascending) { comparator = new ReverseComparator(comparator); } Collections.sort(list, comparator); return list; } /** * */ protected String jsfPageToUrl(String jsfPage) { String result = null; if (jsfPage != null && jsfPage.endsWith(JSF_PAGE_EXTENSION)) { 68

result = jsfPage.replaceAll(JSF_PAGE_EXTENSION, JSF_URL_EXTENSION); } return result; } /** * */ protected String getPage() { final StringBuilder url = new StringBuilder(getFacesContext() .getExternalContext().getRequestContextPath()); url.append(getFacesContext().getViewRoot().getViewId()); return url.toString(); } protected String getUrl() { return jsfPageToUrl(getPage()); } } Algunas de las pginas en JSF necesitarn un formulario. No se debera de llenar los Actions con propiedades que mapeen las salidas del formulario. La mejor opcin es crear una clase, denominada Form, que sirva de Helper para el Action y aglutine esos valores. Todos estas clases Form van a implementar una interfaz que se ha definido en la arquitectura llamada IBaseForm, su utilidad es obligar a todos los formularios a definir un par de mtodos para convertir POJOs en formularios y formularios en POJO. Esto ser til a la hora de crear y modificar las entidades desde los Actions. package org.archetypeUma.forms; import java.io.Serializable; /** * Interface for forms. * * @author jcisneros * @param <K> */ public interface IBaseForm<K> extends Serializable { /** * Gets an entity object from a form object * * @return an entity object */ public K toEntity(); /** * Gets an entity object from a form object * * @return an entity object */ 69

public K toEntity(K Entity); /** * Sets all entity's properties of this form from an entity * * @param entity */ public void fromEntity(K entity); }

4.4.

Convenio de nombres

Es importante seguir una nomenclatura especfica que obligue al grupo de trabajo a utilizar un sistema que ayude a todos a encontrar los ficheros ms rpidamente. La nomenclatura debe de estar en ingls, debe de ser descriptiva y no demasiada larga. Sobre todo los equipos que arreglen las incidencias agradecern la legibilidad del cdigo y su entendimiento. Errores comunes: Es ms fcil encontrar un mtodo que salva un usuario en la clase UserService.java que en MyManager.java. Se identifican mejor las clases si Letras demasiado cortas no son entendibles. saveAUser(user) cambiarlo a saveUser. Se exige desde el punto de vista de la arquitectura que la nomenclatura de los proyectos sea la siguiente: Model: o Los POJOs se llamen igual que la tabla, pero deben de tener el prefijo TABLE_* o VIEW_*. o Las POJOs deben de tener un nombre singular. o Si el POJO es una tabla resultado de una relacin muchos a muchos entonces deber de tener el nombre de las dos tablas. Core Dao: o Las interfaces del Dao deben de empezar por I (de interfaz) y terminar por Dao.java de la siguiente manera I{nombre del POJO}Dao.java o Las implementaciones de las interfaces de la capa DAO deben de empezar por el nombre del POJO y terminar con la terminacin DaoImpl, es decir, {nombre del POJO}DaoImpl.java Core Services: o Las interfaces de la capa service deben de empezar por I (de interfaz) y terminar por Manager.java de la siguiente manera I*Manager.java o Las implementaciones de las interfaces de la capa services deben de empezar por un nombre descriptivo de la funcionalidad que va a tener dicho manager y terminar con la terminacin ServiceImpl, es decir, *ServiceImpl.java Web: o Los Actions de la capa web deben de empezar por un nombre descriptivo de la funcionalidad que va a tener dicho action y terminar con la terminacin Action, es 70

decir, *Action.java o Los forms deben de empezar por el mismo nombre que el Action que los utiliza y terminar por la terminacin Form, quedara algo como esto: UserForm.java o Las pginas xhtml se tienen que encontrar todas metidas en pages y crearse una carpeta para cada funcionalidad. Por ejemplo para la funcionalidad de listar, crear y editar usuarios se ha creado la carpeta /pages/users y dentro de ellas las pginas. list.xhtml y form.xhtml. General: o En toda la aplicacin no pueden coincidir el nombre de dos clases, ya que cuando Spring intenta crear un bean con el mismo nombre suele dar un error que no deja arrancar al servidor.

71

5. Creacin del arquetipo


En este apartado se describe como se ha creado el arquetipo. Primero se explica como se ha trabajado, despus como se ha creado el proyecto y se finaliza con la transformacin del proyecto al arquetipo.

72

5.1.

Infraestructura de desarrollo

El inicio del trabajo ha sido crearse una estructura donde se pueda trabajar con un repositorio. La mejor solucin teniendo en cuenta que este proyecto se entrega como software libre es Google Code.

5.1.1. Google Code


Google Code es una aplicacin web. Podemos encontrarla en http://code.google.com/intl/es-ES/ En este sitio se puede buscar y aadir toda clase de proyectos de cdigo abierto. Es muy intuitivo y bsico. Esa es una de sus bazas y al mismo tiempo una de sus crticas, ya que algunos desarrolladores le han exigido a Google ms potencia en Google Code. A la hora de crear un proyecto nuevo es necesario tener una cuenta en google de correos y entrar logado en Google Code. La pgina para crear los proyectos es http://code.google.com/hosting/createProject donde se dan los primeros pasos para crear el proyecto, nombre, descripcin, licencia.

Figura X: Creacin del proyecto en Google Code. Una vez creado ya solo hay que entrar en el proyecto y trabajar con el. La URL del proyecto es http://code.google.com/p/archetypeuma/ el nombre del proyecto ha sido archetypeUma, por si el lector quiere buscarlo directamente. Google Code proviene de un repositorio con el que se puede conectar a travs de subversion. 73

Al entrar en el proyecto la pestaa Source da la informacin necesaria para conectarse al repositorio.

Figura X: Repositorio svn del proyecto en Google Code. Solo hace falta o un TortoiseSVN o un eclipse con el plugin subclipse para conectarse al repositorio. Ntese que la forma de conectarse ya existen multitud de herramientas, como las distribuciones de Linux que cada una tiene una, ejemplo kdesvn de la distribucin KDE. Se recomienda para agilizar el trabajo en desarrollo que se trabaje con el plugin de eclipse, es ms rpido tenerlo todo integrado en el IDE que estar recorriendo el Sistema operativos en busca de diferentes programas. Una breve descripcin de la importacin del proyecto en eclipse: Creamos un nuevo proyecto Click en new Click en new other

74

Figura X: Creacin del proyecto en Eclipse.

Seleccionamos svn una vez que tengamos el plugin de subclipse instalados.

Figura X: Creacin del proyecto svn en Eclipse. 75

Falta seleccionar la url que contiene el cdigo fuente. La URL del proyecto es: https://archetypeuma.googlecode.com/svn/trunk/ Se crea un proyecto vaco de eclipse. Ya se puede empezar a subir cdigo segn se vaya desarrollando. El men de Google Code esta formado por los siguientes elementos:

Figura X: Los diferentes apartados de Google Code en el proyecto. Project Home: Informacin general del proyecto, descripcin, participantes, licencias y cosas as. Downloads: En este apartado se encuentran los ficheros que son necesarios o recomendados para el buen desarrollo de un proyecto de esta envergadura. Tiene algunas limitaciones como que los ficheros no pueden superar los 100 megas. Por lo que no se pueden adjuntar ficheros como el Jboss AS que debera de estar en este apartado pero que el lector deber de descargrselo de la pgina oficial que se encuentra en el apartado de enlaces. Wiki: Documentacin del proyecto. Se ha organizado por partes lo ms clara posibles. Dejando un apartado llamado QuickStar (Inicio rpido), para los que quieran utilizar el arquetipo y tengan los conocimientos para utilizarlo puedan hacerlo. Issues: Aporta una gestin de las incidencias del proyecto. Son muy tiles para poder tenerlas controladas saber lo que la produjeron y la solucin. Se lleva un control de quien la subi y cuanto a tardado en ser solucionada. Es algo necesario en las tecnologas ITIL Source: En este apartado se muestra como importar el proyecto en los equipos de los usuarios. Esta parte ya ha sido explicada un poco ms arriba. Administer: Administra el sitio con la informacin que se quiera ofrecer al resto de la comunidad del proyecto.

5.2.

Denificin del proyecto

La mayora del trabajo del arquetipo se ha llevado a cabo en la construccin del proyecto en Maven. Se ha pretendido seguir un trabajo lo ms formal posible para que sea entendido por cualquiera que tenga los mnimos conocimientos de Maven. Los properties de Maven estn separados y puestos todos juntos para que todos los submodelos puedan aprovechar las mismas propiedades y que no aparezcan duplicadas por el proyecto. Las propiedades definidas en el proyecto son: <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- Application settings --> <project.groupId>org.archetypeUma</project.groupId> <project.artifactId>archetypeUma</project.artifactId> <war.name>archetypeUma</war.name> 76

<model.version>1.0-SNAPSHOT</model.version> <core.version>1.0-SNAPSHOT</core.version> <web.version>1.0-SNAPSHOT</web.version> <copyright.year>2011</copyright.year> <project.url>http://code.google.com/p/archetypeuma/</project.url> <developer.company>Universidad de Mlaga</developer.company> <dbunit.maven.version>1.0-beta-3</dbunit.maven.version> <deploy.maven.version>2.4</deploy.maven.version> <aspectj.version>1.6.1</aspectj.version> <tomcat.maven.version>1.0-alpha-1</tomcat.maven.version> <eclipse.maven.version>2.8</eclipse.maven.version> <jboss.maven.version>1.3.1</jboss.maven.version> <war.maven.version>2.1-beta-1</war.maven.version> <!-- Database settings --> <dbunit.dataTypeFactoryName>org.dbunit.ext.mysql.MySqlDataTypeFactory</dbunit.dataTypeFa ctoryName> <dbunit.operation.type>CLEAN_INSERT</dbunit.operation.type> <jdbc.groupId>mysql</jdbc.groupId> <jdbc.artifactId>mysql-connector-java</jdbc.artifactId> <jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName> <jdbc.version>5.0.8</jdbc.version> <jdbc.host>localhost</jdbc.host> <jdbc.port>3306</jdbc.port> <jdbc.dbname>archetype_db</jdbc.dbname> <jdbc.username>archetype_user</jdbc.username> <jdbc.password>archetype_pwd</jdbc.password> <jdbc.url><![CDATA[jdbc:mysql://${jdbc.host}:${jdbc.port}/${jdbc.dbname}? createDatabaseIfNotExist=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf8]]></jdbc.url> <hibernate.annotations.version>3.4.0.GA</hibernate.annotations.version> <hibernate.dialect>org.hibernate.dialect.MySQLDialect</hibernate.dialect> <hibernate.version>3.5.1</hibernate.version> <!-- Hibernate Maven Plugin --> <hibernate3.maven.version>2.2</hibernate3.maven.version> <hbm2ddl.drop.model>true</hbm2ddl.drop.model> <cobertura.version>1.9.4</cobertura.version> <!-- Eclipse Maven Plugin --> <eclipse.maven.version>2.8</eclipse.maven.version> <eclipse.maven.wtp.version>1.5</eclipse.maven.wtp.version> <eclipse.maven.downloadSources>true</eclipse.maven.downloadSources> <eclipse.maven.downloadJavadocs>true</eclipse.maven.downloadJavadocs> <eclipse.maven.useProjectReferences>false</eclipse.maven.useProjectReferences> <eclipse.maven.useProjectReferences.webProjects>true</eclipse.maven.useProjectReferences.web Projects> <eclipse.maven.default.buildOutputDirectory>target/classes</eclipse.maven.default.buildOutputDir ectory> <!-- Dependency --> 77

<slf4j.version>1.6.0</slf4j.version> <jsf-myfaces.version>2.0.2</jsf-myfaces.version> <junit.version>4.0</junit.version> <jsf-tomahawk.version>1.1.10</jsf-tomahawk.version> <jsf-primefaces.version>2.2.RC2</jsf-primefaces.version> <spring.version>3.0.5.RELEASE</spring.version> <hibernate.dependency.version>3.5.6-Final</hibernate.dependency.version> <oscache.version>2.4</oscache.version> <mysql-connector-java.version>5.0.8</mysql-connector-java.version> <jmock-junit4.version>2.5.1</jmock-junit4.version> <commons-beanutils.version>1.7.0</commons-beanutils.version> <junit.version>4.5</junit.version> <commons-dbcp.version>1.3</commons-dbcp.version> <javassist.version>3.9.0.GA</javassist.version> <log4j.version>1.2.16</log4j.version> <ehcache.version>1.5.0</ehcache.version> <oscache.version>2.4</oscache.version> <!-- plugins versions --> <source.version>1.6</source.version> <maven-compiler-plugin.version>2.3.2</maven-compiler-plugin.version> <maven-war-plugin.version>2.1</maven-war-plugin.version> <maven-surefire-plugin.version>2.6</maven-surefire-plugin.version> <maven-jetty-plugin.version>6.1.25</maven-jetty-plugin.version> <maven-ear-plugin.version>2.4.2</maven-ear-plugin.version> </properties> Una vez preparado un sistema de properties se han desglosado el proyecto en los diferentes poms y se ha creado una estructura del proyecto acorde a lo que maven necesita. La estructura de proyecto ha quedado de la siguiente forma:

Figura X. Estructura del proyecto que genera el arquetipo. Se definen todos los elementos de que maven necesita y se completan todos los poms, enganchndose entre si para que se ejecuten en el orden preciso. 78

A continuacin se describen los plugins utilizados en el arquetipo que da solucin a la arquitectura: maven-eclipse-plugin es un plugin que permite crear un proyecto eclipse a partir de un proyecto Maven. Este plugin no es necesario meterlo en todos los proyecto porque ya funciona con el modulo normal de Maven3 pero si se quiere modificar alguna de sus propiedades si que hay que redefinirlo. En este caso se ha cambiado las carpetas de salida de los cdigos fuente, se obliga a tener soporte para Spring y se exige que se descargue el cdigo fuente de las bibliotecas que utilice el proyecto. Las propiedades estn especificadas mediante properties de Maven, se ruega al lector que para ms detalle se descargue el cdigo del proyecto.

<plugin> <artifactId>maven-eclipse-plugin</artifactId> <version>${eclipse.maven.version}</version> <configuration> <buildOutputDirectory>${eclipse.maven.default.buildOutputDirectory}</buildOutputDirectory> <additionalProjectnatures> <projectnature>org.springframework.ide.eclipse.core.springnature </projectnature> </additionalProjectnatures> <additionalBuildcommands> <buildcommand>org.springframework.ide.eclipse.core.springbuilder </buildcommand> </additionalBuildcommands> <downloadSources>${eclipse.maven.downloadSources}</downloadSources> <downloadJavadocs>${eclipse.maven.downloadJavadocs}</downloadJavadocs> <wtpversion>${eclipse.maven.wtp.version}</wtpversion> <useProjectReferences>${eclipse.maven.useProjectReferences}</useProjectReferences> </configuration> </plugin> maven-war-plugin: es el plugin que empaqueta la aplicacin en un war. Este plugin no es obligatorio si se quiere usar el empaquetado estndar, en este proyecto, al ser de maven3 y no de maven2 se ha tenido que redefinir utilizando la versin 2.1-beta-1 del plugin.

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1-beta-1</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <archive> <manifest> <addClasspath>true</addClasspath> <addExtensions/> <classpathPrefix/> </manifest> </archive> </configuration> </plugin>

79

maven-compiler-plugin: es el plugin que permite a Maven compiler. No es obligatorio hacer referencia a l en los pom pero si es necesario si se quiere cambiar la versin. Este plugin cuando para por el ciclo de vida compile, copilara todos los ficheros java que estn en las carpetas correctas.

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> <source>${source.version}</source> <target>${source.version}</target> </configuration> </plugin> hibernate3-maven-plugin: este plugin permite crear la base de datos a partir de los POJOs que estn definidos con las anotaciones de JPA. <groupId>org.codehaus.mojo</groupId> <artifactId>hibernate3-maven-plugin</artifactId> <version>${hibernate3.maven.version}</version> <executions> <execution> <phase>test-compile</phase> <goals> <goal>hbm2ddl</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>${jdbc.groupId}</groupId> <artifactId>${jdbc.artifactId}</artifactId> <version>${jdbc.version}</version> </dependency> <dependency> <groupId>net.sourceforge.cobertura</groupId> <artifactId>cobertura</artifactId> <version>${cobertura.version}</version> </dependency> </dependencies> <configuration> <components> <component> <name>hbm2ddl</name> <implementation>annotationconfiguration</implementation> </component> </components> <componentProperties> <drop>${hbm2ddl.drop.model}</drop> <jdk5>true</jdk5> 80

<plugin>

<propertyfile>target/classes/jdbc.properties</propertyfile> <skip>${maven.test.skip}</skip> <outputfilename>${hbm2ddl.outputfile.model}</outputfilename> </componentProperties> </configuration> </plugin> dbunit-maven-plugin: este plugin rellena los valores en la base de datos, para tener un juego de datos rico y con el que poder hacer pruebas. Los datos los rellena a partir del xml que se defina en el fichero src/main/resources/sample-data.xml.

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>dbunit-maven-plugin</artifactId> <version>${dbunit.maven.version}</version> <executions> <execution> <phase>test-compile</phase> <goals> <goal>operation</goal> </goals> <configuration> <dataTypeFactoryName>$ {dbunit.dataTypeFactoryName}</dataTypeFactoryName> <src>src/main/resources/sample-data.xml</src> <type>${dbunit.operation.type}</type> </configuration> </execution> </executions> <configuration> <driver>${jdbc.driverClassName}</driver> <username>${jdbc.username}</username> <password>${jdbc.password}</password> <url>${jdbc.url}</url> <schema>${dbunit.schema}</schema> <skip>${maven.test.skip}</skip> <skipOracleRecycleBinTables>true</skipOracleRecycleBinTables> <useQualifiedTableNames>false</useQualifiedTableNames> </configuration> <dependencies> <dependency> <groupId>${jdbc.groupId}</groupId> <artifactId>${jdbc.artifactId}</artifactId> <version>${jdbc.version}</version> </dependency> </dependencies> </plugin> maven-jetty-plugin: permite gestionar el servidor Jetty a partir de la lnea de comandos y sin la necesidad de bajarse directamente el servidor Jetty. Aadiendo por consola de comandos: mvn jetty:run es suficiente para arrancar el proyecto y poder utilizarlo con normalidad. 81

<plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>${maven-jetty-plugin.version}</version> <configuration> AJAX Push server deployment <jettyConfig>jetty.xml</jettyConfig> <contextPath>/</contextPath> <scanIntervalSeconds>3</scanIntervalSeconds> <scanTargetPatterns> <scanTargetPattern> <directory>src/main/webapp/WEB-INF</directory> <excludes> <exclude>**/*.jsp</exclude> <exclude>**/*.xhtml</exclude> </excludes> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> </scanTargetPattern> </scanTargetPatterns> </configuration> </plugin> Lo siguiente es instalar cada componente de la arquitectura. Esto se explica en el siguiente apartado.

5.3.

Instalacin de los frameworks en el arquetipo

En este capitulo se describe la instalacin de todos los frameworks y herramientas utilizadas para el desarrollo del arquetipo. Ha sido necesario instalar Java, Maven3, una base de datos, uno de los servidores y todas las libreras. Si desde la consola de comandos se invoca al plugin de Maven que da todas las dependencias del proyecto. Se puede apreciar el trabajo que se ha hecho en meter dependencias y comprobar que no hay incoherencias entre ellas. El comando para ver las dependencias sera: mvn dependency:tree [INFO] Scanning for projects... [INFO] -----------------------------------------------------------------------[INFO] Reactor Build Order: [INFO] [INFO] Proyecto de la Universidad de Malaga de un archetype de maven3 [INFO] archetypeUma - Model [INFO] archetypeUma - Core [INFO] archetypeUma - Web [INFO] 82

[INFO] -----------------------------------------------------------------------[INFO] Building Proyecto de la Universidad de Malaga de un archetype de maven3 1.0SNAPSHOT [INFO] -----------------------------------------------------------------------[INFO] [INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ archetypeUma --[INFO] org.archetypeUma:archetypeUma:pom:1.0-SNAPSHOT [INFO] [INFO] -----------------------------------------------------------------------[INFO] Building archetypeUma - Model 1.0-SNAPSHOT [INFO] -----------------------------------------------------------------------[INFO] [INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ archetypeUma-model --[INFO] org.archetypeUma:archetypeUma-model:jar:1.0-SNAPSHOT [INFO] +- org.hibernate:hibernate-core:jar:3.5.6-Final:compile [INFO] | +- antlr:antlr:jar:2.7.6:compile [INFO] | +- commons-collections:commons-collections:jar:3.1:compile [INFO] | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | \- xml-apis:xml-apis:jar:1.0.b2:compile [INFO] | \- javax.transaction:jta:jar:1.1:compile [INFO] +- org.slf4j:slf4j-api:jar:1.6.0:compile [INFO] +- org.hibernate:hibernate-annotations:jar:3.5.6-Final:compile [INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile [INFO] | \- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.0.Final:compile [INFO] +- org.hibernate:hibernate-entitymanager:jar:3.5.6-Final:compile [INFO] | \- cglib:cglib:jar:2.2:compile [INFO] | \- asm:asm:jar:3.1:compile [INFO] +- javassist:javassist:jar:3.9.0.GA:runtime (scope not updated to compile) [INFO] +- log4j:log4j:jar:1.2.16:compile [INFO] +- org.slf4j:slf4j-log4j12:jar:1.6.0:compile [INFO] +- net.sf.ehcache:ehcache:jar:1.5.0:compile [INFO] | +- backport-util-concurrent:backport-util-concurrent:jar:3.1:compile [INFO] | +- commons-logging:commons-logging:jar:1.0.4:compile [INFO] | \- net.sf.jsr107cache:jsr107cache:jar:1.0:compile [INFO] \- opensymphony:oscache:jar:2.4:compile [INFO] +- javax.jms:jms:jar:1.1:compile [INFO] \- javax.servlet:servlet-api:jar:2.3:compile [INFO] [INFO] -----------------------------------------------------------------------[INFO] Building archetypeUma - Core 1.0-SNAPSHOT [INFO] -----------------------------------------------------------------------[INFO] [INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ archetypeUma-core --[INFO] org.archetypeUma:archetypeUma-core:jar:1.0-SNAPSHOT [INFO] +- org.archetypeUma:archetypeUma-model:jar:1.0-SNAPSHOT:compile [INFO] | +- org.hibernate:hibernate-core:jar:3.5.6-Final:compile [INFO] | | +- antlr:antlr:jar:2.7.6:compile [INFO] | | +- commons-collections:commons-collections:jar:3.1:compile [INFO] | | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | | \- xml-apis:xml-apis:jar:1.0.b2:compile [INFO] | | \- javax.transaction:jta:jar:1.1:compile [INFO] | +- org.hibernate:hibernate-annotations:jar:3.5.6-Final:compile 83

[INFO] | | +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile [INFO] | | \- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.0.Final:compile [INFO] | +- org.hibernate:hibernate-entitymanager:jar:3.5.6-Final:compile [INFO] | | +- cglib:cglib:jar:2.2:compile [INFO] | | | \- asm:asm:jar:3.1:compile [INFO] | | \- javassist:javassist:jar:3.9.0.GA:compile [INFO] | +- log4j:log4j:jar:1.2.16:compile [INFO] | +- org.slf4j:slf4j-log4j12:jar:1.6.0:compile [INFO] | +- org.slf4j:slf4j-api:jar:1.6.0:compile [INFO] | \- net.sf.ehcache:ehcache:jar:1.5.0:compile [INFO] | +- backport-util-concurrent:backport-util-concurrent:jar:3.1:compile [INFO] | \- net.sf.jsr107cache:jsr107cache:jar:1.0:compile [INFO] +- opensymphony:oscache:jar:2.4:compile [INFO] | +- commons-logging:commons-logging:jar:1.1:compile [INFO] | | +- logkit:logkit:jar:1.0.1:compile [INFO] | | \- avalon-framework:avalon-framework:jar:4.1.3:compile [INFO] | +- javax.jms:jms:jar:1.1:compile [INFO] | \- javax.servlet:servlet-api:jar:2.3:compile [INFO] +- org.springframework:spring-context:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:3.0.5.RELEASE:compile [INFO] | | \- aopalliance:aopalliance:jar:1.0:compile [INFO] | +- org.springframework:spring-beans:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-core:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-expression:jar:3.0.5.RELEASE:compile [INFO] | \- org.springframework:spring-asm:jar:3.0.5.RELEASE:compile [INFO] +- org.springframework:spring-test:jar:3.0.5.RELEASE:test (scope not updated to compile) [INFO] +- junit:junit:jar:4.5:test [INFO] +- commons-beanutils:commons-beanutils:jar:1.7.0:compile [INFO] +- org.springframework:spring-orm:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-jdbc:jar:3.0.5.RELEASE:compile [INFO] | \- org.springframework:spring-tx:jar:3.0.5.RELEASE:compile [INFO] +- org.jmock:jmock-junit4:jar:2.5.1:test [INFO] | +- org.jmock:jmock:jar:2.5.1:test [INFO] | | +- org.hamcrest:hamcrest-core:jar:1.1:test [INFO] | | \- org.hamcrest:hamcrest-library:jar:1.1:test [INFO] | \- junit:junit-dep:jar:4.4:test [INFO] +- commons-dbcp:commons-dbcp:jar:1.3:compile [INFO] | \- commons-pool:commons-pool:jar:1.5.4:compile [INFO] +- mysql:mysql-connector-java:jar:5.0.8:compile [INFO] \- org.springframework:spring-aspects:jar:3.0.5.RELEASE:compile [INFO] \- org.springframework:spring-context-support:jar:3.0.5.RELEASE:compile [INFO] [INFO] -----------------------------------------------------------------------[INFO] Building archetypeUma - Web 1.0-SNAPSHOT [INFO] -----------------------------------------------------------------------[INFO] [INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ archetypeUma-web --[INFO] org.archetypeUma:archetypeUma-web:war:1.0-SNAPSHOT [INFO] +- org.springframework.security:spring-security-web:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework.security:spring-security-core:jar:3.0.5.RELEASE:compile [INFO] | | +- org.springframework:spring-expression:jar:3.0.3.RELEASE:compile [INFO] | | +- org.springframework:spring-aop:jar:3.0.3.RELEASE:compile 84

[INFO] | | +- org.aspectj:aspectjrt:jar:1.6.8:compile [INFO] | | \- org.aspectj:aspectjweaver:jar:1.6.8:compile [INFO] | \- org.springframework:spring-web:jar:3.0.3.RELEASE:compile [INFO] | \- aopalliance:aopalliance:jar:1.0:compile [INFO] +- org.springframework.security:spring-security-config:jar:3.0.5.RELEASE:compile [INFO] +- org.springframework:spring-test:jar:3.0.5.RELEASE:test (scope not updated to compile) [INFO] +- org.springframework:spring-orm:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-core:jar:3.0.5.RELEASE:compile [INFO] | | \- org.springframework:spring-asm:jar:3.0.5.RELEASE:compile [INFO] | +- org.springframework:spring-jdbc:jar:3.0.5.RELEASE:compile [INFO] | \- org.springframework:spring-tx:jar:3.0.5.RELEASE:compile [INFO] +- org.archetypeUma:archetypeUma-core:jar:1.0-SNAPSHOT:compile [INFO] | +- org.archetypeUma:archetypeUma-model:jar:1.0-SNAPSHOT:compile [INFO] | | +- org.hibernate:hibernate-core:jar:3.5.6-Final:compile [INFO] | | | +- antlr:antlr:jar:2.7.6:compile [INFO] | | | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | | \- javax.transaction:jta:jar:1.1:compile [INFO] | | +- org.hibernate:hibernate-annotations:jar:3.5.6-Final:compile [INFO] | | | +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile [INFO] | | | \- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.0.Final:compile [INFO] | | +- org.hibernate:hibernate-entitymanager:jar:3.5.6-Final:compile [INFO] | | | +- cglib:cglib:jar:2.2:compile [INFO] | | | | \- asm:asm:jar:3.1:compile [INFO] | | | \- javassist:javassist:jar:3.9.0.GA:compile [INFO] | | +- log4j:log4j:jar:1.2.16:compile [INFO] | | +- org.slf4j:slf4j-log4j12:jar:1.6.0:compile [INFO] | | +- org.slf4j:slf4j-api:jar:1.6.0:compile [INFO] | | \- net.sf.ehcache:ehcache:jar:1.5.0:compile [INFO] | | +- backport-util-concurrent:backport-util-concurrent:jar:3.1:compile [INFO] | | \- net.sf.jsr107cache:jsr107cache:jar:1.0:compile [INFO] | +- org.springframework:spring-context:jar:3.0.5.RELEASE:compile [INFO] | +- commons-beanutils:commons-beanutils:jar:1.7.0:compile [INFO] | +- commons-dbcp:commons-dbcp:jar:1.3:compile [INFO] | | \- commons-pool:commons-pool:jar:1.5.4:compile [INFO] | +- mysql:mysql-connector-java:jar:5.0.8:compile [INFO] | +- opensymphony:oscache:jar:2.4:compile [INFO] | | +- javax.jms:jms:jar:1.1:compile [INFO] | | \- javax.servlet:servlet-api:jar:2.3:compile [INFO] | \- org.springframework:spring-aspects:jar:3.0.5.RELEASE:compile [INFO] | \- org.springframework:spring-context-support:jar:3.0.5.RELEASE:compile [INFO] +- org.apache.myfaces.core:myfaces-api:jar:2.0.2:compile [INFO] +- org.apache.myfaces.core:myfaces-impl:jar:2.0.2:runtime [INFO] | \- commons-discovery:commons-discovery:jar:0.4:runtime [INFO] +- org.apache.myfaces.tomahawk:tomahawk20:jar:1.1.10:compile [INFO] | +- commons-logging:commons-logging:jar:1.1.1:compile [INFO] | +- commons-validator:commons-validator:jar:1.3.1:compile [INFO] | | \- commons-digester:commons-digester:jar:1.8:compile [INFO] | | \- xml-apis:xml-apis:jar:1.0.b2:compile [INFO] | +- commons-fileupload:commons-fileupload:jar:1.2.1:compile [INFO] | +- commons-io:commons-io:jar:1.3.2:runtime [INFO] | +- commons-collections:commons-collections:jar:3.2.1:compile 85

[INFO] | +- commons-codec:commons-codec:jar:1.3:compile [INFO] | +- oro:oro:jar:2.0.8:compile [INFO] | +- commons-lang:commons-lang:jar:2.4:compile [INFO] | +- javax.servlet:jstl:jar:1.2:compile [INFO] | \- batik:batik-awt-util:jar:1.6-1:compile [INFO] | \- batik:batik-util:jar:1.6-1:compile [INFO] | \- batik:batik-gui-util:jar:1.6-1:compile [INFO] | \- batik:batik-ext:jar:1.6-1:compile [INFO] | \- xml-apis:xmlParserAPIs:jar:2.0.2:compile [INFO] +- org.primefaces:primefaces:jar:2.2.RC2:compile [INFO] \- junit:junit:jar:4.5:test [INFO] -----------------------------------------------------------------------[INFO] Reactor Summary: [INFO] [INFO] Proyecto de la Universidad de Malaga de un archetype de maven3 SUCCESS [0.813s] [INFO] archetypeUma - Model .............................. SUCCESS [0.187s] [INFO] archetypeUma - Core ............................... SUCCESS [0.203s] [INFO] archetypeUma - Web ................................ SUCCESS [0.375s] [INFO] -----------------------------------------------------------------------[INFO] BUILD SUCCESS [INFO] -----------------------------------------------------------------------[INFO] Total time: 1.812s [INFO] Finished at: Thu Feb 03 09:24:55 CET 2011 [INFO] Final Memory: 6M/247M [INFO] -----------------------------------------------------------------------Tabla X. Dependencias del arquetipo

5.3.1.

JAVA

Hay que empezar instalando la mquina virtual de java porque sino el resto de herramientas no funcionarn. Los principales navegadores de Internet y algunos sistemas operativos ya vienen con la mquina virtual de java instalados. Aunque siempre se le ofrece paquetes, a los usuarios de programas Java, que son accesibles desde la red y puede bajarse en http://sun.java.es Los paquetes JDK (Java Developers Kits) contienen un sistema de compilacin y de interpretacin para los desarrolladores de programas Java. Los paquetes de instalacin tanto en Windows los ficheros exe o en Linux (suele traer java ya instalado), suelen instalar todo lo necesario para su uso. Se suele incluir una variable de entorno JAVA_HOME y se incluye el directorio bin en el path, para poder ejecutar java desde cualquier ubicacin en el sistema de ficheros.

86

5.3.2.

Maven

Requisitos obligatorios: JDK de JAVA, recomendada la versin 1.6 El trabajo consiste en la creacin de un arquetipo de Maven, por lo tanto es necesario instalarse la ltima versin de Maven: http://Maven.apache.org/download.html , la descarga se puede realizar desde la pgina de este proyecto. Maven necesita una serie de variables de entorno para funcionar, se aaden a continuacin las que seran necesarias y la forma de hacerlo en cada entorno: En linux: o export MAVEN_HOME=/home/user/carpetasInstalacion/apache-Maven-3.0 o export M2_REPO=/home/user/carpetasInstalacion/repositorioMaven o export M2=/home/user/carpetasInstalacion/apache-Maven-3.0 o export MAVEN_OPTS=-Xms512 -Xmx512 -XX:MaxPermSize=512m En windows: o set MAVEN_HOME=/C:/carpetasInstalacion/apache-Maven-3.0 o set M2_REPO=/C:/carpetasInstalacion/apache-Maven-3.0 o set M2=/C:/carpetasInstalacion/apache-Maven-3.0 o export MAVEN_OPTS=-Xms512 -Xmx512 -XX:MaxPermSize=512m

Solo faltara meter Maven en el path del sistema operativo, para poder ejecutarlo desde cualquier punto del sistema de ficheros: En linux: o export PATH=$PATH:$MAVEN_HOME/bin En windows: o set PATH=$PATH;$MAVEN_HOME/bin

Los ficheros de configuracin de Maven pueden verse en diferentes niveles: Global: $M2_HOME/conf/settings.xml Por usuario: ~/.m2/settings.xml Por proyecto: pom.xml

5.3.3.

Frameworks JAVA

El arquetipo esta compuesto por una serie de frameworks, estos frameworks son libreras de JAVA que hay que ir aadiendo al proyecto uno a uno e instalando correctamente. Se va a describir como se han instalado cada framework en el arquetipo:

5.3.3.1. Myfaces 2.0


Se aade en el pom.xml del proyecto web las dependencias al core de myfaces 2.0: 87

<dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-api</artifactId> <version>2.0.2</version> </dependency> <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-impl</artifactId> <version>2.0.2</version> </dependency> El servlet encargado del funcionamiento de myfaces es FacesServlet, hay que declararlo en web.xml junto a unos parmetros de configuracin de myfaces2.0. <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> Hace falta aadir un fichero faces-config.xml con las reglas de navegacin de las pginas jsf. Tambin se declara otros elementos y componentes de jsf. <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> </faces-config>

5.3.3.2. Primefaces 2.0


Requisitos obligatorios: Myfaces 2.0 u otra implementacin de JSF 2.0 Para instalarlo hay que meter la dependencia en el pom.xml de la capa web. <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>2.0.2</version> </dependency> En el fichero web.xml hay que declarar que se va a utilizar el servlet de primefaces: 88

<servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class>org.primefaces.resource.ResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/primefaces_resource/*</url-pattern> </servlet-mapping>

5.3.3.3. Tomahawk 2.0


Requisitos obligatorios: Myfaces 2.0 u otra implementacin de JSF 2.0 Hay que incluir la dependencia hacia la librera de Tomahawk: <dependency> <groupId>org.apache.myfaces.tomahawk</groupId> <artifactId>tomahawk20</artifactId> <version>1.1.10</version> </dependency> En el fichero web.xml hay que declarar el filtro que se ocupa de los recursos de Tomahawk <filter> <filter-name>extensionsFilter</filter-name> <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class> <init-param> <description>Set the size limit for uploaded files. Format: 10 10 bytes 10k - 10 KB 10m - 10 MB 1g - 1 GB</description> <param-name>uploadMaxFileSize</param-name> <param-value>100m</param-value> </init-param> <init-param> <description>Set the threshold size - files below this limit are stored in memory, files above this limit are stored on disk. Format: 10 - 10 bytes 10k - 10 KB 10m - 10 MB 1g - 1 GB</description> <param-name>uploadThresholdSize</param-name> <param-value>100k</param-value> </init-param> </filter> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>*.html</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>/faces/*</url-pattern> 89

</filter-mapping>

5.3.4. Spring Framework


Spring es requisitos en muchos otros frameworks, obtienen su configuracin a partir de los beans definidos en Spring. Lo primero es meter las dependencias de Spring en el pom.xml. <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.0.5.RELEASE</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.0.5.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>3.0.5.RELEASE</version> </dependency> Es necesario incluir las dependencias con el sistema de logs para que Spring funcione correctamente y tenga soporte para trazas. <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.5.8</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.5.8</version> <scope>runtime</scope> </dependency> 90

<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.5.8</version> <scope>runtime</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> <scope>runtime</scope> </dependency> En las aplicaciones web hay que configurar un listener que es el encargado de Spring de levantar el contexto y preparar la configuracin de Spring. Esto se hace en el fichero de descripcin web.xml. <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> La variable contextConfigLocation es la encargada de definir los ficheros XML de spring que tienen la configuracin de la aplicacin: <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/spring/applicationContext-dao.xml classpath:/spring/applicationContext-service.xml classpath:/spring/applicationContext-security.xml </param-value> </context-param> En este caso hay tres ficheros que tienen la configuracin de Spring. Uno para la capa DAO, otro para la capa Service y el ltimo para la configuracin de Spring Security. Aunque se podra hacer todo en un solo fichero es mejor tenerlos ordenados ya que estos ficheros en proyectos grandes suelen crecer fcilmente.

5.3.5. Hibernate
Requisitos obligatorios: Mysql o Postgresql Requisitos opcionales: Spring Frameworks Hibernate necesita estas dependencias para funcionar correctamente dentro de un proyecto: <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.5.0-CR-2</version> </dependency> 91

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.0-CR-2</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>3.5.0-CR-2</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.9.0.GA</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>1.5.0</version> </dependency> <dependency> <groupId>opensymphony</groupId> <artifactId>oscache</artifactId> <version>2.4<version> </dependency> Es necesario crear una serie de beans de Spring para que la aplicacin sepa cual es el Datasource y dems configuraciones de Hibernate. Estos son los beans que se han declarado: propertyConfigurer: se especifica el fichero de propiedades de la conexin de la base de datos. Actualmente apunta a jdbc.properties. Fichero que tiene las propiedades de la base de datos. dataSource: en este bean se especifica cual es la fuente de datos que se va a utilizar contra la base de datos. Se ha puesto el BasicDataSource como datasource por defecto pero se puede cambiar y poner el que ms convenga al entorno con el que se este trabajando. sessionFactory: es un bean necesario para Hibernate en el cual se guarda toda la informacin de configuracin que necesita. Utiliza los dos beans anteriores para definir alguna parte de toda la gama de valores que posee.

applicationContext-resource.xml 92

<?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:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:jdbc.properties</value> </list> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroymethod="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxActive" value="100" /> <property name="maxWait" value="10000" /> <property name="defaultAutoCommit" value="true" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <property name="hibernateProperties"> <value> hibernate.dialect=${hibernate.dialect} hibernate.query.substitutions=true 'Y', false 'N' hibernate.cache.use_second_level_cache=true hibernate.cache.use_query_cache=true hibernate.cache.provider_class=org.hibernate.cache.OSCacheProvider </value> </property> <property name="entityInterceptor"> <ref bean="entityAuditLogInterceptor" /> </property> </bean> Hibernate se configura en el fichero hibernate.cfg.xml. hibernate.xfg.xml

93

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="java:hibernate/SessionFactory"> <property name="hibernate.generate_statistics">true</property> <property name="hibernate.connection.pool_size">50</property> <property name="hibernate.session_factory_name">java:hibernate/SessionFactory</property> <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</pro perty> <property name="hibernate.current_session_context_class">jta</property> <property name="hibernate.max_fetch_depth">1</property> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.provider_class"> org.hibernate.cache.OSCacheProvider </property> <property name="hibernate.cache.use_query_cache">true</property> <property name="hibernate.cache.use_structured_entries">true</property> <mapping class="org.archetypeUma.model.pojos.City" /> <mapping class="org.archetypeUma.model.pojos.User" /> </session-factory> </hibernate-configuration> Todos los valores se pueden consultar en la documentacin. Lo ms destacable es que se utiliza Oscache como segundo nivel de cache de hibernate, mediante su provider OSCacheProvider. Oscache necesita tener un fichero oscache.properties definido en el classpath para poder funcionar: oscache.properties cache.capacity=10000 En l se define que abra una cache de 10000 objetos JAVA.

5.3.6. Spring Security


Requisitos obligatorios: Proyecto Java con Spring Frameworks En el fichero pom.xml del subproyecto web debe de estar la dependencia con Spring Security. <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.0.5.RELEASE</version> 94

</dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.0.5.RELEASE</version> <scope>compile</scope> </dependency> Cuando se compile el proyecto. Se recorrer la dependencia y Maven se dar cuenta que la necesita y la obtendr de uno de sus repositorios. Hay que aadir en el fichero web.xml el filtro de Spring Security. <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> Y las url que van a ser mapeadas. En este caso las aceptaremos todas. Aunque se puede prescindir de imgenes, javascripts y ese tipo de ficheros. <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> La configuracin de Spring Security se hace a travs de beans. Se aade al contexto de Spring los beans necesarios para que funcione Spring Security. Esto se hace en el fichero applicationContextsecurity.xml. Web.xml <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/spring/applicationContext-security.xml </param-value> </context-param> applicationContext-security.xml Es obligatorio tener un fichero que declare los beans de Spring Security. Este fichero tiene que tener declarado el espacio de nombres en su cabecera: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd"> <http auto-config="true"> <intercept-url pattern="/**" access="ROLE_ANONYMOUS" /> 95

</http> <authentication-manager> <authentication-provider> <user-service> <user name="admin" password="admin" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager> </beans>

5.3.7. Log4j
Hay que incluir en el proyecto la dependencia con el jar. Es probable y sobre todo si la aplicacin es grande que la dependencia ya esta incluida en el proyecto porque sea dependencia de otro jar que ya tengamos en los pom.xml. <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> Es imprescindible tener un fichero de propiedades o un xml en el classpath del proyecto. El fichero log4j.xml es el que har las veces de fichero de configuracin de log4j. En la seccin de 'Uso' hay un ejemplo de fichero de configuracin. log4.xml <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%p [%t] %c{1}.%M(%L) | %m%n"/> </layout> </appender> <appender name="FILE" class="org.apache.log4j.RollingFileAppender"> <param name="Threshold" value="INFO" /> <param name="File" value="librae.log" /> <param name="Append" value="true" /> <param name="MaxFileSize" value="500KB" /> <param name="MaxBackupIndex" value="1" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%c] %m%n" /> </layout> </appender> <logger name="org.hibernate"> <level value="INFO/> </logger> <logger name="org.apache"> <level value="INFO"/> 96

</logger> <root> <level value="ERROR"/> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> </log4j:configuration>

5.3.8. Framework para los test 5.3.8.1. JUnit


Maven utiliza determinados ciclos de vida solo para la ejecucin de test. Pero necesita la dependencia con la Api de JUnit, hay que meterla en el pom.xml: <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.5</version> <scope>test</scope> </dependency> Los beans de Spring necesitan ser inyectados para las pruebas. Es necesario insertar la dependencia a la librera Spring-test: <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.0.3.RELEASE</version> </dependency>

5.3.8.2. JMock
Solo hay que meter en el pom.xml la dependencia al jar de JMock. <dependency> <groupId>org.jmock</groupId> <artifactId>jmock-junit4</artifactId> <version>2.5.1</version> <scope>test</scope> </dependency>

5.3.8.3. JMeter
JMeter es una aplicacin que hay que instalar en el equipo, hay dos versiones separadas segn el 97

sistema operativo: Windows: http://code.google.com/p/archetypeuma/downloads/detail?name=jakarta-jmeter2.4.zip&can=2&q=#makechanges Descromprimir el fichero y entrar en la carpeta bin. Abrir el ejecutable jmeter.bat Linux: http://code.google.com/p/archetypeuma/downloads/detail?name=jakarta-jmeter2.4.tgz&can=2&q=#makechanges Descomprimir y desde la consola situada en el directorio bin ejecutar: sh jmeter.sh

5.4.

Generacin del arquetipo

Bien, ya estara declarada la estructura del proyecto, preparado el cdigo de Maven y las dependencias. Se ha implementado un ejemplo de cada uno de los frameworks. Es el momento de transformar el proyecto en un arquetipo para que los usuarios se puedan descargar el proyecto e instalarlo en sus mquinas locales. Llegando a este punto habra un proyecto bien formado y corriendo en el servidor local. Hay que transformar el cdigo de un proyecto normal en un arquetipo. Se han ejecutados los siguientes pasos para llevarlo a cabo: mvn archetype:create-from-project Crea un carpeta con los datos que maven necesita sobre el arquetipo, despus hay que entrar en esa carpeta: cd target/generated-sources/archetype/ Hay que compilar esata carpeta: mvn clean install Ya estara preparado el arquetipo para ser usado en local, se usara la orden: mvn archetype:generate -DarchetypeCatalog=local Lo suyo es hacer antes un mvn clean y un mvn eclipse:clean para que no nos queden por ah ficheros indeseables en un arquetipo.

98

6. Trabajando con la arquitectura


6.1. Preparacin y descarga

La maquina virtual de java es requisito imprescindible para que el programa se ejecute correctamente. Es muy probable que el usuario ya tenga instalado en su computadora la mquina virtual de java sobre la que se ejecuta la aplicacin pero si no la tiene puede obtenerla de http://java.sun.com. El proyecto necesita la versin 1.6 de la JDK de Java. Ms informacin de la instalacin de Java. Una vez este instalada la maquina virtual ya se puede correr cualquier aplicacin java. El primer paso sera instalarnos Maven. Tenemos un enlace al manual de instalacin Maven. Ahora se puede invocar al arquetipo ArchetypeUma con una de las siguientes dos llamadas, dependiendo de la versin de Maven3 que este instalada: mvn archetype:generate -DremoteRepositories=https://archetypeuma.googlecode.com/svn/trunk/archetype-catalog.xml -DarchetypeGroupId=org.archetypeUma -DarchetypeArtifactId=archetypeUma-archetype -DarchetypeVersion=1.0-SNAPSHOT mvn archetype:generate -DarchetypeRepository=https://archetypeuma.googlecode.com/svn/trunk -DarchetypeGroupId=org.archetypeUma -DarchetypeArtifactId=archetypeUma-archetype -DarchetypeVersion=1.0-SNAPSHOT Se crearn unas carpetas y ficheros en el directorio que tengamos el shell o consola de Windows. Por lo que es conveniente que se cree en el directorio de trabajo en el que vaya a correr eclipse. Una vez descargado el proyecto entero, se puede continuar trabajando, pero antes hay que en trar en el fichero pom.xml y cambiar la propiedad war.name y poner el nombre del artifactId que se le haya puesto al proyecto. <war.name>archetypeUma</war.name> A continuacin hay que instalar la base de datos. Ya sea MySQL o Postgresql o cualquiera otra base de datos si se cambia el driver y la dependencia que esta en el pom.xml principal. Bien, si esta instalada hay que crear una base de datos y un usuario que tenga permisos para eso: create database archetype_db; Se crea el usuario: CREATE USER 'archetype_user'@'localhost' IDENTIFIED BY 'archetype _pwd'; GRANT ALL PRIVILEGES ON *.* TO 'archetype_user'@'localhost' IDENTIFIED BY 'archetype 99

_pwd' WITH GRANT OPTION; Esta base de datos y usuario se ha creado as porque en el arquetipo viene con ese nombre y ese password. Se puede poner el que quiera si se cambian las lneas en el pom.xml principal del proyecto. Estas son las lneas que habra que sustituir: <jdbc.dbname>archetype_db</jdbc.dbname> <jdbc.username>archetype_user</jdbc.username> <jdbc.password>archetype_pwd</jdbc.password> Dependiendo del IDE en el que se quiera instalar hay que integrarlo, para esto existe los goals de Maven: Eclipse mvn eclipse:clean eclipse:eclipse Intellij IDEA mvn idea:clean idea:idea

Esto tardar un poco. Ya que adems de crear el proyecto y descargarse las dependencias propias del plugin, se descarga todos los cdigos fuentes que se utiliza en el proyecto. Este proyecto al tener tantas dependencias tarda bastante en bajrselas todas. Se arranque el servidor: Cd web Mvn jetty:run Y se acecede a la aplicacin: http://localhost:8080/artifactId/index.htm

6.2.

Utilizacin de la arquitectura

El arquetipo se entrega con un ejemplo bsico. Funcionalmente el comportamiento es sencillo. Tiene el siguiente funcionamiento:

Figura X. Caso de uso en el arquetipo Hay un listado de usuarios, desde el que se puede aadir o editar. Para empezar, se va a mostrar como se ha creado este ejemplo. Partiendo del problema inicial. El problema inicial es crear un 100

mantenimiento para el usuario. Se empieza desde la capa ms inferior, la tabla usuario en la base de datos.

6.2.1.

Model

Como se explica en el apartado de POJO's, lo primero que habra que hacer cuando se necesita una tabla en un modelo entidad relacin es transformar esa tabla a un objeto de JAVA. Una vez hecho un estudio sobre que POJO's se necesitan para resolver un problema habra que empezar a crearlos, teniendo en cuenta unas reglas: A la hora de crear el POJO es importante heredar de la clase BaseObjetc.java para implementar los mtodos que hay en esta clase. Todos y cada uno de los valores que se inserten o se modifiquen en la clase hay que crearlos un getters y un setters para que los frameworks puedan modificarlos sin problemas invocando a estos mtodos. Los campos se crean mediante anotaciones JPA, (lea el apartado de Hibernate con anotaciones JPA o acuda a un manual de JPA de los enlaces relaciones con este proyecto) Es un requisito obligatorio que la base de datos este normalizada, cuente con su propia clave primaria y todas las relaciones entre tablas cumplan las reglas de normalizacin.

El usuario esta relacionado con la ciudad, ya que cada usuario vive en una ciudad. En la memoria se va a presentar el cdigo de la ciudad porque el del usuario es ms grande. En el ejemplo de una ciudad el cdigo quedara: City.java package org.archetypeUma.model.POJOs; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.SequenceGenerator; import javax.persistence.Table; @Entity(name = City.ENTITY_NAME) @Table(name = City.TABLE_NAME) public class City extends BaseObject { private static final long serialVersionUID = 7550335133725207117L; public static final String ENTITY_NAME = "org.archetype.model.POJOs.City"; public static final String TABLE_NAME = "TABLE_CITY"; private static final String ID_GENERATOR_NAME = "GENERATOR_CITY"; private static final String ID_SEQUENCE_NAME = "SEQ_CITY"; public static final String COLUMN_NAME_ID = "PK_CITY"; public static final String COLUMN_NAME_CODE = "CODE_CITY"; public static final String COLUMN_NAME_NAME = "NAME_CITY";

101

private Long private String private String protected City() { super(); }

id; code; name;

public City(String code, String nombre) { super(); this.code = code; this.name = nombre; } @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = ID_GENERATOR_NAME) @SequenceGenerator(name = ID_GENERATOR_NAME, sequenceName = ID_SEQUENCE_NAME) @Column(name = City.COLUMN_NAME_ID) public Long getId() { return id; } protected void setId(Long id) { this.id = id; } @Column(name = COLUMN_NAME_CODE, length = 100) public String getCode() { return code; } public void setCode(String code) { this.code = code; } @Column(name = COLUMN_NAME_NAME, length = 100) public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof City)) { 102

return false; } final City other = (City) obj; if (!getCode().equals(other.getCode())) { return false; } return true; } public int hashCode() { final int prime = 31; int result = prime; result += ((id == null) ? 0 : getId().hashCode()); result = prime * result + ((getCode() == null) ? 0 : getCode().hashCode()); return result; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(COLUMN_NAME_ID).append(getId()).append(" "); sb.append(COLUMN_NAME_CODE).append(getCode()).append(" "); sb.append(COLUMN_NAME_NAME).append(getName()).append(" ").toString(); return sb.toString(); } } Despus hay que registrar el POJO para que hibernate lo reconozca cuando se levante el contexto de la aplicacin. Esto se hace en el fichero de configuracin de hibernate: hibernate.cfg.xml Se aade la lnea: <mapping class="org.archetypeUma.model.POJOs.City" /> Con el fin de tener una base de datos competente que tenga un juego de datos variados, hay que aadir todas las tuplas que sea necesario a las tablas que se van a crear en base de datos. Esto se inserta en el fichero sample-data.xml. Es un fichero en formato XML que mediante el plugin de Hibernate se transformar en los valores de la base de datos. sample-data.xml <?xml version="1.0" encoding="UTF-8"?> <dataset> <table name="table_city"> <column>PK_CITY</column> <column>CODE_CITY</column> <column>NAME_CITY</column> <row> <value description="PK_CITY">-1</value> <value description="CODE_CITY">MA</value> 103

<value description="NAME_CITY">Mlaga</value> </row> <row> <value description="PK_CITY">-2</value> <value description="CODE_CITY">GR</value> <value description="NAME_CITY">Granada</value> </row> <row> <value description="PK_CITY">-3</value> <value description="CODE_CITY">CA</value> <value description="NAME_CITY">Cdiz</value> </row> </table> </dataset> Se aaden 3 ciudades a la tabla CITY en la base de datos. Mlaga, Granada y Cdiz con sus respectivos cdigos e identificadores. Se hara lo mismo para el usuario.

6.2.2.

Core

Lo primero debe de ser crear la capa DAO. Hay que crear una interfaz y su implementacin para esta capa. Como ejemplo se adjunta el DAO del POJO City. Con el POJO User se hace lo mismo. Primero se declara la interfaz: ICityDao.java package org.archetypeUma.dao.interfaces; import org.archetypeUma.model.pojos.City; public interface ICityDao extends IBaseDao<City, Long> { List<City> getAllCache(); } A continuacin se declara la implementacin de la interfaz anterior. CityImpl.java package org.archetypeUma.dao.implementation; import org.archetypeUma.dao.interfaces.ICityDao; import org.archetypeUma.model.pojos.City; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Repository; @Repository("cityDao") public class CityDaoImpl extends BaseDaoImpl<City, Long> implements ICityDao { 104

@Autowired public CityDaoImpl(SessionFactory sessionFactory) { super(sessionFactory, City.class); } public List<City> getAllCache() { List<City> result = null; HibernateTemplate ht = this.getHibernateTemplate(); ht.setCacheQueries(true); result = ht.loadAll(City.class); return result; } } Con el fin de aportar cierta calidad al cdigo se deben de realizar los test, claro esta que depende del proyecto, de su complejidad y del tiempo. Este sera el test para la clase ICityDao.java ICityDaoTest.java package org.archetypeUma.dao; import static org.junit.Assert.assertEquals; import java.util.List; import org.archetypeUma.dao.interfaces.ICityDao; import org.archetypeUma.model.pojos.City; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:/spring/applicationContext-resources.xml", "classpath:/spring/applicationContext-dao.xml"}) public class ICityDaoTest { @Autowired private ICityDao cityDao; @Test public void testGetAll() { List<City> cities = cityDao.getAll(); assertEquals(3, cities.size()); } public void setCityDao(ICityDao cityDao) { this.cityDao = cityDao; 105

} } Es imprescindible inyectar con @Autowired la capa DAO y declarar en la cabecera como se llaman los XML de Spring que tienen la informacin de los beans, para ello esta la anotacin @ContextConfiguration. Cada mtodo de una clase debera de tener uno o varios test. En el que se prueben los casos positivos y los negativos e intentar llevar el cdigo a donde pueda fallar. Este mdulo tiene su propia gestin de logs. Se configura desde el fichero log4j.xml que hay en core/resources/log4j.xml La capa Service rene la lgica de negocio de la aplicacin. La funcionalidad que se esta resolviendo es la gestin de usuarios, por lo tanto, se crea una clase llamada IUserManager.java para que la resuelva. IUserManager.java package org.archetypeUma.service.interfaces; import java.io.Serializable; import java.util.List; import org.archetypeUma.dao.interfaces.ICityDao; import org.archetypeUma.dao.interfaces.IUserDao; import org.archetypeUma.model.pojos.City; import org.archetypeUma.model.pojos.User; import org.springframework.transaction.annotation.Transactional; @Transactional(readOnly = true) public interface IUserManager extends Serializable { /** * Get all users. * * @return users. */ List<User> getAll(); /** * Get all cities. * * @return cities. */ List<City> getAllCity(); /** * Save user. * * @param user */ 106

@Transactional(readOnly = false) User save(User user, Long idCity); /** * Get user for id. * * @param user */ User getUser(Long idUser); // Setters for test void setUserDao(IUserDao userDao); void setCityDao(ICityDao cityDao); } Hay que implementar los mtodos que aqu se definen, esto se hace en UserManager.java UserManagerImpl.java package org.archetypeUma.service.implementation; import java.util.Date; import java.util.List; import org.archetypeUma.dao.interfaces.ICityDao; import org.archetypeUma.dao.interfaces.IUserDao; import org.archetypeUma.model.pojos.City; import org.archetypeUma.model.pojos.User; import org.archetypeUma.service.interfaces.IUserManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; /** * Service from users. * * @author jcisneros */ @Service(value = "userManager") public class UserManagerImpl implements IUserManager { private static final long serialVersionUID = 23323323L; @Autowired @Qualifier("userDao") private IUserDao userDao = null; @Autowired @Qualifier("cityDao") 107

private ICityDao cityDao = null; /** * {@inheritDoc} */ public List<User> getAll() { return userDao.getAll(); } /** * {@inheritDoc} */ public List<City> getAllCity() { return cityDao.getAllCache(); } /** * {@inheritDoc} */ public User save(User user, Long idCity) { City city = cityDao.get(idCity); user.setCity(city); user.setDateCreation(new Date()); return userDao.merge(user); } /** * {@inheritDoc} */ public User getUser(Long idUser) { return userDao.get(idUser); } // Getters && Setters public void setUserDao(IUserDao userDao) { this.userDao = userDao; } public void setCityDao(ICityDao cityDao) { this.cityDao = cityDao; } } Ahora hay que crear los test, se puede utilizar o JUnit o JMock. Como las capas inferiores ya se han debido de haber probado en ICityDaoTest.java, se va a utilizar JMock entendiendo que la capa inferior es un Mock que funciona correctamente. IUserManagerTest.java package org.archetypeUma.services;

108

import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import org.archetypeUma.dao.interfaces.ICityDao; import org.archetypeUma.dao.interfaces.IUserDao; import org.archetypeUma.model.pojos.City; import org.archetypeUma.model.pojos.User; import org.archetypeUma.service.implementation.UserManagerImpl; import org.archetypeUma.service.interfaces.IUserManager; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JMock; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(JMock.class) public class IUserManagerTest { // Mock context private Mockery context = new Mockery();

private IUserManager userManager = null; private IUserDao private ICityDao userDao = context.mock(IUserDao.class); cityDao = context.mock(ICityDao.class);

@Before public void setUp() { userManager = new UserManagerImpl(); userManager.setUserDao(userDao); userManager.setCityDao(cityDao); } @Test public void testGetAll() { final List<User> usuarios = new ArrayList<User>(); usuarios.add(new User("jcisneros", "javier")); context.checking(new Expectations() { { one(userDao).getAll(); will(returnValue(usuarios)); } }); assertEquals(userManager.getAll(), usuarios); context.assertIsSatisfied(); } @Test public void testGetAllCity() { 109

final List<City> cities = new ArrayList<City>(); cities.add(new City("MA", "Mlaga")); context.checking(new Expectations() { { one(cityDao).getAllCache(); will(returnValue(cities)); } }); assertEquals(userManager.getAllCity(), cities); context.assertIsSatisfied(); } // Getters && Setters } Esta capa terminara con el acceso a dato y la lgica de negocio de los usuarios terminados .

6.2.3.

Web

Este mdulo tiene su propia gestin de logs. Se configura desde el fichero log4j.xml que hay en web/resources/log4j.xml. En la parte web hay que separar cuando hay que implementar la vista y cuando hay que implementar los Actions.

6.2.3.1. Action
Cuando se habla de controlador en JSF se hace referencia a los Actions. En esta arquitectura cada Action dar servicios a pginas diferentes y grupos funcionales diferentes. Los Actions son clases Java que tienen una funcionalidad que hay que realizar en el servidor. Resuelven eventos que los usuarios van creando en las pginas El ejemplo de la creacin de un usuario queda de la siguiente forma: UserFormAction.java package org.archetypeUma.actions; import java.io.Serializable; import javax.annotation.PreDestroy; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.RequestScoped; import org.archetypeUma.forms.UserForm; import org.archetypeUma.model.pojos.User; 110

import org.archetypeUma.service.interfaces.IUserManager; @ManagedBean(name = "userFormAction") @RequestScoped public class UserFormAction extends BaseAction implements Serializable { private static final long serialVersionUID = 1234124123412L; @ManagedProperty(value = "#{userManager}") private IUserManager userManager = null; private UserForm userForm = new UserForm(); @ManagedProperty("#{param.idUser}") private Long idUser = null; public UserFormAction() { } @PreDestroy public void destroy() { } public String done() { String page = "list"; try { User user = null; if ((userForm.getIdUser() == null) || (userForm.getIdUser().equals(new Long(0)))) { user = userForm.toEntity(); } else { user = userManager.getUser(userForm.getIdUser()); user = userForm.toEntity(user); } user = userManager.save(user, userForm.getCity()); } catch (Exception e) { log.error(e.getMessage()); page = "form"; } return page; } public String edit() { String page = "list"; try { User user = null; if (idUser != null) { user = userManager.getUser(idUser); userForm.fromEntity(user); page = "form"; } } catch (Exception e) { } 111

return page; } // Getters && Setters public void setUserManager(IUserManager userManager) { this.userManager = userManager; } public UserForm getUserForm() { return userForm; } public void setUserForm(UserForm userForm) { this.userForm = userForm; } protected IUserManager getUserManager() { return userManager; } public Long getIdUser() { return idUser; } public void setIdUser(Long idUser) { this.idUser = idUser; } } Es importante dotar al cdigo con las anotaciones necesarias para que las llamadas entre capas se realice. Si se necesita utilizar el manager de usuario hay que hacer una invocacin con: @ManagedProperty(value = "#{userManager}") No se puede olvidar los getters y setters con los que Myfaces y Spring invocan a las propiedades. En este caso, la pgina tiene un formulario. No se debera de llenar los Actions con propiedades que mapeen las salidas del formulario. La mejor opcin es crear una clase, denominada Form, que sirva de Helper para el Action y aglutine esos valores. En el arquetipo el ejemplo de esta variante se ha llamado UserForm.java y representa el formulario de creacin de un formulario: UserForm.java package org.archetypeUma.forms; import java.io.IOException; import java.io.InputStream; import java.util.Date; import org.apache.myfaces.custom.fileupload.UploadedFile; import org.archetypeUma.model.pojos.User; 112

import org.springframework.util.FileCopyUtils; public class UserForm implements IBaseForm<User> { private Long idUser; private String nick; private String name; private Long city; private Date dateCreation; private UploadedFile image; private byte[] imageDB; public void fromEntity(final User user) { if (user != null) { setIdUser(user.getId()); setNick(user.getNick()); setName(user.getName()); if (user.getCity() != null) { setCity(user.getCity().getId()); } if (user.getImage() != null) { setImageDB(user.getImage()); } setDateCreation(user.getDateCreation()); } } public User toEntity() { final User user = new User(getNick(), getName()); toEntity(user); return user; } public User toEntity(final User user) { user.setNick(getNick()); user.setName(getName()); // image if (getImage() != null) { try { final InputStream inputS = getImage().getInputStream(); if (inputS != null) { user.setImage(FileCopyUtils.copyToByteArray(inputS)); } } catch (final IOException e) { } user.setImageContentType(getImage().getContentType()); } return user; } // Getters && Setter public Long getIdUser() { 113

return idUser; } public void setIdUser(Long idUser) { this.idUser = idUser; } public String getNick() { return nick; } public void setNick(String nick) { this.nick = nick; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getCity() { return city; } public void setCity(Long city) { this.city = city; } public UploadedFile getImage() { return image; } public void setImage(UploadedFile image) { this.image = image; } public byte[] getImageDB() { return imageDB; } public void setImageDB(byte[] imageDB) { this.imageDB = imageDB; } public Date getDateCreation() { return dateCreation; } public void setDateCreation(Date dateCreation) { 114

this.dateCreation = dateCreation; } } Es necesario que cada propiedad que represente un campo del formulario de JSF2 sea creada junto a getter y setter, sino el valor no se almacenar en el objeto asignado para ello.

6.2.3.2. Vista
La pgina XHTML puede interactuar con el Action cuando necesite alguna lgica del servidor. La forma de relacionarse es invocando al mismo nombre que ha sido definido en la cabecera del Action: @ManagedBean(name = "userFormAction") Desde la pgina de creacin / edicin de usuario puede llamarse a este bean llamado userFormAction: form.xhtml <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html" xmlns:t="http://myfaces.apache.org/tomahawk" template="/templates/template.xhtml"> <ui:define name="content"> <h:head> <title><h:outputText value="#{i18n['userEdit.title']}" /></title> </h:head> <h:body syleClass="body"> <h:form id="formUsers" enctype="multipart/form-data"> <span class="title"><h:outputText value="#{i18n['userEdit.title']}" styleClass="headTitle"/></span> <t:panelGrid columns="3" styleClass="table" headerClass="headTable" footerClass="footTable" cellpadding="0" cellspacing="0" border="0" width="100%" columnClasses="width20,width50,width30"> <h:outputLabel id="labelNick" for="nick" value="#{i18n['userEdit.nick']}" styleClass="label"/> <h:inputText styleClass="input" size="80" id="nick" value="#{userFormAction.userForm.nick}" required="true" maxlength="80" /> <t:message for="nick" styleClass="fieldError" detailFormat="{1} #{i18n['required']}." showSummary="false" showDetail="true" /> <h:outputLabel id="labelName" for="name" value="#{i18n['userEdit.name']}" styleClass="label"/> <h:inputText styleClass="input" size="80" id="name" value="#{userFormAction.userForm.name}" required="true" maxlength="80" /> <t:message for="name" styleClass="fieldError" detailFormat="{1} #{i18n['required']}." 115

showSummary="false" showDetail="true" /> <h:outputLabel id="labelCity" for="city" value="#{i18n['userEdit.city']}" styleClass="label"/> <h:selectOneMenu id="city" value="#{userFormAction.userForm.city}" styleClass="input" size="80"> <f:selectItems value="#{combosAction.cities}" /> </h:selectOneMenu> <t:message for="city" styleClass="fieldError" detailFormat="{1} #{i18n['required']}." showSummary="false" showDetail="true" /> <t:inputHidden id="idUser" value="#{userFormAction.userForm.idUser}"/> </t:panelGrid> <t:commandButton id="buttonDone" styleClass="buttonDone" value="#{i18n['button.done']}" action="#{userFormAction.done}"/> <t:commandButton id="buttonBack" styleClass="buttonBack" value="#{i18n['button.back']}" action="list" immediate="true"/> </h:form> </h:body> </ui:define> </ui:composition> La primera parte ui:composition corresponde con las libreras que se podrn utilizar en la pgina y con el template que se va a utilizar: template="/templates/template.xhtml", en este caso el nico que hay definido en el proyecto. <ui:define name="content"> define en que parte del template va a ir alojado este cdigo. En el value de algunos componentes se hace referencia al Action, por ejemplo para obtener la ciudad seleccionada en el combo de ciudades se hace mencin al formulario y se le invoca de la siguiente manera: <h:selectOneMenu id="city" value="#{userFormAction.userForm.city}" Ficheros de properties:

La internacionalizacin en JSF 2 se resuelve de forma que existe un fichero de propiedades con la extensin del idioma con el que el navegador esta invocando al servidor para que le sirva la pgina. Se han definido el fichero de propiedades por defecto, en espaol y en ingls. add=Add update=Update remove=Remove title=ArchetypeUma users=Users userEdit.nick=Nick userEdit.name=Name userEdit.city=City userEdit.image=Image userEdit.title=User edit login=Login login.nick=Nick login.password=Password 116

login.title=Login required=is required button.done=Aceptar button.back=Volver button.back=Cancel footer.uma=Universidad de Mlaga footer.informatica.uma=Escuela Tcnica Superior de Ingeniera Informtica El servlet de Myfaces es muy riguroso con los properties, lanza un error en el servidor si no encuentra la property. Recursos estticos:

Se ha definido en el fichero template.xhtml los siguientes properties: <h:outputStylesheet name="styles.css" library="css"/> <h:outputStylesheet name="skin.css" library="css"/> Se pueden aadir tantos como se quiera, tanto de javacripts o de css.

117

118

7. Herramientas para el uso de la arquitectura


7.1. IDE

Un IDE es un entorno de desarrollo integrado que permite editar programas en java, compilarlos, ejecutarlos, depurarlos, construir rpidamente el interfaz grco de una aplicacin eligiendo los componentes de una paleta, y muchas cosas ms. Hay varios IDE's en el mercado entre los que destacan Eclipse, Netbeans e Intellij IDEA.

7.1.1. Eclipse
En la web oficial de Eclipse (www.eclipse.org), se define como An IDE for everything and nothing in particular (un IDE para todo y para nada en particular). Eclipse es, en el fondo, nicamente un armazn (workbench) sobre el que se pueden montar herramientas de desarrollo para cualquier lenguaje, mediante la implementacin de los plugins adecuados. La arquitectura de plugins de Eclipse permite, dems de integrar diversos lenguajes sobre un mismo IDE, introducir otras aplicaciones accesorias que pueden resultar tiles durante el proceso de desarrollo como: herramientas UML, editores visuales de interfaces, ayuda en lnea para libreras, etc. En su origen, el Proyecto Eclipse era un proyecto de desarrollo OpenSource, soportado y mantenido en su totalidad por IBM. Bajo la direccin de IBM, se fund el Consorcio Eclipse al cual se unieron algunas empresas importantes como Rational, HP o Borlan Desde el da 2 de febrero de 2004, el Consorcio Eclipse es independiente de IBM y entre otras, est formado por las empresas: HP, QNX, IBM, Intel, SAP, Fujitsu, Hitachi, Novell, Oracle, Palm, Ericsson y RedHat, adems de algunas universidades e institutos tecnolgicos. Eclipse es una aplicacin Java que se ejecuta en una maquina virtual. Tiene dos ficheros de arranque dependiendo de si estamos en Windows (eclipse.exe) o en Linux (eclipse.sh) que ejecutaremos cuando se instale el programa. Si lo lanzamos desde un ejecutable tambin puede que se cree la variable global ECLIPSE_HOME. Esta es la estructura de directorios que tiene eclipse: Si se pretende ampliar la funcionalidad de eclipse con un nuevo plugin hay que pegar la carpeta que traiga el plugin en las carpetas de plugins y features. Eclipse permite una gran variedad de aplicaciones webs, aplicaciones standalone, plugins y ms para desarrollar.

119

Si se quiere importar un proyecto de Maven, como es el caso de estudio, hay que ir a nuevo proyecto y presionar en el men - Seleccionar proyecto desde el espacio de trabajo. Se selecciona el proyecto y Aceptar. Esto insertar en el espacio de trabajo el proyecto un proyecto Maven con el que eclipse solo servir de editor. Como eclipse en este caso no compilar y solo lo servir de editor de fichero se continuar la explicacin de como se usa en el apartado QuickStart. El proyecto en Maven hay que importarlo a eclipse mediante un mvn eclipse:eclipse. Esto trae los cdigos fuentes de los jars y los relaciona con el proyecto. A continuacin habra que importar el proyecto en eclipse como un Project exist in workspace. Esto hace que todas las referencias de eclipse dependan de una variable local que hay que insertar en eclipse. Es M2_REPO y se mete en el men de herramientas

7.1.2. Netbeans
Un IDE Java completo y modular. Entre sus principales caractersticas: Soporte Out-of-box para Java SE, Java EE, Java ME. Gran conjunto de mdulos de terceros (plug-in's). Desarrollo intuitivo con drag-and-drop. Debugger, Profiler, Refactoring y muchas cosas ms.

Es un software gratuito y open-source desde Junio de 2000. Es mantenido por una extensa comunidad de usuarios y desarrolladores. Naci como un proyecto estudiantil en Repblica Checa en 1996. Su nombre original era Xelfi. Xelfi fue el primer IDE para Java, escrito en Java. Jarda Tulach, miembro del equipo original propone el nombre NetBeans: Network + Java Beans = NetBeans Es un IDE que tiene algunas partes declaradas como cdigo abierto. Tiene licencia Apache 2.0. Integra algunas herramientas como JavaScript, Spring, Hibernate, Struts, GWT, app servers, VCS, inspections, Eclipse interop, Maven, J2ME, JUnit. La estructura de carpetas de Netbeans es mucho ms compleja que la de eclipse y por eso no la vamos a explicar con tanto detalle. Solo hacer especial mencin a que en la carpeta bin esta el ejecutable. Netbans en su instalacin da la opcin de instalar varios servidores y bases de datos, todos de software libre. Lo mejor es aprovechar la ocasin para instalarse Apache Tomcat o Glassfish. Por otro lado, Netbeans que es una aplicacin de Java y escrita 100% en cdigo Java permite que se utilice otros lenguajes en su entorno, se esta incorporando cada vez ms funcionalidad para Phyton, Ruby, PHP o C++.

120

El uso de estos IDEs depende de la funcionalidad con las que se quiera utilizar. Se pueden aadir y quitar funcionalidad desde el Menu superior Clic en Windows Clic en Plugins y aparece un men como el de la imagen donde se puede seleccionar ms plugins y modulos.

Figura X. Incluir un nevo mdulo o plugin a Netbeans.

El directorio de trabajo de Netbeans se guarda en el directorio de trabajo del usuario de Windows o Linux: Windows: o C:\Documents and Settings\Cisneros\Mis documentos\NetBeansProjects Linux: o /home/{nombre_usuario}/NetBeansProjects

Por defecto, Netbeans ya integra Maven en sus proyectos. Para importar el proyecto Maven hay que pulsar sobre New Project en el men superior y despus seleccionar Maven e incluir como proyecto a partir de un pom existente.

121

Figura X. Incluir el proyecto Maven en Netbeans. Como usar Maven con Netbeans? 1.En el men seleccionar Herramientas plugins. 2.En la seccin Plugins disponibles seleccionar el plugin Maven y hacer clic en Instalar. 3.Reiniciar Netbeans, con eso netbeans reconoce y permite crear proyectos maven desde su men.

7.1.3. Intellij IDEA


IntelliJ IDEA es un IDE desarrollado por JetBrains. IntelliJ IDEA se autodefine como un entorno inteligente para desarrollar aplicaciones Java, cliente y servidor. Efectivamente, se trata de un completsimo IDE que tambin permite desarrollar aplicaciones para mviles (J2ME). IntelliJ IDEA posee un avanzado editor de cdigo, compatible con multitud de tecnologas (AJAX, JSP, EJB) y, dentro de un mismo entorno, ofrece anlisis del cdigo, compilacin/ejecucin/debugging, control de versiones, deteccin de duplicaciones, anlisis de dependencias y soporte para plugins. Esta es la estructura de carpetas de IntelliJ IDEA. Los ejecutables se meten en la carpeta bin, las libreras que necesita la aplicacin en lib y en la carpeta plugins se meten las extensiones para el IDE.

122

Figura X. Carpetas de Intellij IDEA El uso de Intellij IDEA es similar a los dos descritos anteriormente.

Figura X. Vista del espacio de trabajo de Intellij IDEA

7.2.

Base de datos

La base de datos es la memoria a largo plazo de la aplicacin. La arquitectura utiliza Hibernate para comunicarse con la base de datos. Entre las bases de datos probadas estan Mysql y Postgresql, pero se puede aadir cualquiera que tengan compatibilidad con Hibernate.

123

7.2.1. MySQL
Mysql es una base de datos relacional y un sistema de gestin de bases de datos relacional, multiusuario y multihilo. Al ser un sistema gestor adems de una base de datos le da la virtud de poder crear bases de datos y manipularlos, por medio de creaciones, modificaciones y eliminaciones. Mysql es desarrollada por MYSQL AB fundada en suecia en 1995 y cuyos fundadores son David Axmark, Allan Larsson, y Michael "Monty" Widenius. MYSQL AB actualmente es una subsidiaria de Sun Microsystem filial a su vez de Oracle Corporation. Tiene licencia de software libre GNU GPL. Mysql utiliza SQL (Structure Query Language, Lenguaje de Consulta Estructurado) que es un lenguaje de programacin estndar para la gestin de bases de datos. Es una base de datos muy segura, rpida y fcil de usar. Mysql consta de un servidor de bases de datos, varios programas utilitarios que ayudan a la gestin de la base de datos y algn software de apoyo que necesita el servidor de base de datos. Adems es interesante instalarse un gestor de bases de datos ms comercial, ya que el que trae mysql por defecto es para lneas de comandos y hay herramientas muy elaboradas que pueden apoyar bastante a la creacin y manipulacin de bases de datos. Los tipos de datos son muy importantes en cada base de datos porque estn muy ligados al motor de base de datos que se utiliza. En este documento no se entrara al detalle porque desde la arquitectura se recomienda utilizar el plugin de maven que crea los tipos de datos que el cree oportuno. Esto se explica en ms detalle en el apartado de Hibernate. Mysql como cualquier base de datos relacional funciona mediante rdenes SQL. Existen una gran variedad de rdenes que invitamos al usuario a que aprenda.

7.2.2. Postgresql
PostgreSQL es un sistema de gestin de base de datos relacional orientada a objetos y sotware libre, publicado bajo la licencia BSD. Como muchos otros proyectos de cdigo abierto, el desarrollo de PostgreSQL no es manejado por una empresa y/o persona, sino que es dirigido por una comunidad de desarrolladores que trabajan de formas desinteresadas, altruistas, libres y/o apoyadas por organizaciones comerciales. Dicha comunidad es denominada el PGDG (PostgreSQL Global Development Group). PostgreSQL ha tenido una larga evolucin, la cual se inicia en 1982 con el proyecto Ingres en la Universidad de Berkeley. Este proyecto, liderado por Michael Stonebraker. Para el ao 1996 se unieron al proyecto personas ajenas a la Universidad como Marc Fournier de Hub.Org Networking Services, Bruce Momjian y Vadim B. Mikheev quienes proporcionaron el primer servidor de desarrollo no universitario para el esfuerzo de desarrollo de cdigo abierto y comenzaron a trabajar para estabilizar el cdigo de Postgres95. La funcionalidad de postgresql es parecida a la de mysql pero intenta mejorar algunos aspectos: o Alta concurrencia. o Amplia variedad de tipos nativos. Esta base de datos se asemeja bastante a Oracle y es un buen sustituto para los que hayan trabajado 124

con ella pero quieran software libre. DBUnit tiene un problema con esta base de datos. Ya que DBUnit intenta eliminar el esquema de la base de datos desde el mismo esquema de base de datos que esta utilizando y eso en Postgresql da error. Habra que eliminarlo desde otro esquema de base de datos. El mismo problema se puede presentar en otras bases de datos, por ejemplo en Oracle.

7.3.

Servidores de aplicaciones

En este apartado la arquitectura ha sido probada en un contenedor de servlets y jps y en un servidor de aplicaciones. Los ms famosos y por tanto ms utilizados son Apache Tomcat y Jboss. En el desarrollo se recomienda que se utilice Jboss y para la puesta en produccin utilizaremos Jboss.

7.3.1. Apache Tomcat


Apache Tomcat es un contenedor de servlets y JSP. Es un software de cdigo abierto creado y mantenido por la comunidad de Apache. Tiene licencia Apache License version 2. Actualmente es el contenedor de servlets ms utilizado por su velocidad y su robustez. La ltima versin es la 7.1 que soporta la especificaciones ms modernas, Servlet 3.0, JSP 2.2 y EL 2.2. Tomcat no es un servidor de aplicaciones, como JBoss. Incluye el compilador Jasper, que compila JSPs convirtindolas en servlets. El motor de servlets de Tomcat a menudo se presenta en combinacin con el servidor web Apache 2.0. Esta es la es la estructura de carpetas que tiene el Apache Tomcat:

Figura X: Estructura de carpetas de Apache Tomcat. Una breve descripcin de la utilizad de cada carpeta: bin: Se guardan todas las aplicaciones software que trae Apache Tomcat. Encontramos aplicaciones para arrancar el servidor, para pararlo y algunas ms. Conf: es el directorio de configuracin. Destacan los ficheros server.xml, web.xml y context.xml ya que son los que controlan las caractersticas que va a tener el Tomcat definido. Lib: aqu tiene cabida las libreras Java que utiliza Tomcat para su ejecucin. Este directorio 125

tambin es utilizado en algunos proyectos cuando se quiere compartir libreras entre diferentes aplicaciones desplegadas en Tomcat. Logs: se crean los ficheros de logs. Es bueno mandar los ficheros de logs a esta carpeta para tener centralizados los logs. Temp: Carpeta temporal de Tomcat que seguramente pasar de desapercibida para el usuario. Webapps: en esta carpeta es la que utiliza Tomcat para desplegar las aplicaciones. Contiene varios proyectos de prueba y la aplicacin de administracin de Tomcat.

A varias formas de utilizar el servidor de Tomcat. Las ms utilizadas son el arranque desde la consola de comandos y desde el eclipse. Arranque desde la consola de comandos: o En Windows: /carpetaInstalacion/apache-tomcat-7.0.0/bin/catalina.bat run o en Linux /carpetaInstalacion/apache-tomcat-7.0.0/bin/catalina.sh run

Arrancar todos los proyectos que hay en la carpeta de webapps de tomcat y los que se definan en el fichero context.xml El servidor se detiene con el programa shutdown.bat o shutdown.sh segn estemos en Windows o en Linux. Arranque desde el Eclipse: o Eclipse incluye un plugin con el que se permite interactuar directamente con el servidor desde el propio Eclipse. Si el eclipse que esta utilizando el usuario no lo incluye se puede descargar desde http://www.eclipse.org/webtools/ Para relacionar el Eclipse con Tomcat desde Eclipse hay que clickear en New - Server Seleccionar Apache Tomcat. Esto crear un nuevo proyecto en el workspace llamado server. Este proyecto contiene un fichero llamado context.xml. Se aade un contexto nuevo cuando queramos aadir un nuevo proyecto basado en el arquetipo. De la siguiente forma: <Context autoDeploy="true" cookies="true" crossContext="false" docBase="/home/user/archetypeUma/web/target/archetypeUma" path="/archetypeUma" reloadable="true"/> Creando un contexto para el proyecto archetypeUma en la ruta que se define en docBase.

7.3.2. JBoss AS
Jboss Aplication Server es un servidor de aplicaciones basado en el software libre. Ha sido desarrollado por Jboss una divisin de Red Hat adquirida en el 2006. JBoss implementa todo el paquete de servicios de J2EE. Jboss es definido como un EJB Container y utiliza un contenedor de servlet para ser un Servlet Constainer. Tomcat es el Servlet Container por defecto de Jboss As pero puede desacoplarse y acoplarse el contenedor que quisiramos si cumple las condiciones que exige Jboss. An teniendo tanta funcionalidad va a hacer falta un balanceador o frontal para poner las aplicaciones en Internet. Apache 2 suele ser el ms utilizado. 126

Esta es la es la estructura de carpetas que tiene el Jboss AS:

Figura X: Estructura de carpetas de Jboss AS. Una breve descripcin de la utilizad de cada carpeta: bin: Se guardan todas las aplicaciones software que trae Jboss AS. Encontramos aplicaciones para arrancar el servidor, para pararlo y algunas ms. Estan los .bat para Windows y los .sh para Linux. client: almacena los ficheros de configuracin y las libreras JAR, las cuales son necesarias para una aplicacin cliente JAVA o un contenedor del servlets. docs: contiene los XML y DTDs usados en JBoss para las referencias. Hay documentacin de la configuracin y conexiones a bases de datos (caso de MySQL, Oracle, Postgres). lib: Libreras Java (JAR) las cuales son necesarias para usar el JBoss microkernel. Esta carpeta puede ser utilizada para incluir libreras que van a ser utilizadas a nivel de todas las aplicaciones que tenga el servidor de aplicaciones, si es que contiene ms de una. Server: cada directorio que contenga esta carpeta ser una aplicacin diferente. Por defecto cualquier versin de Jboss AS trae 3 instancias: o minimal: es la configuracin minima del servidor. o default: es la configuracin estndar del servidor. o all: es la configuracin ms completa del servidor. Contiene todo lo necesario para que Jboss se ejecute en cluster, tenga servicios web y muchas cosas ms. A varias formas de utilizar el servidor de Tomcat. Las ms utilizadas son el arranque desde la consola de comandos y desde el eclipse. Arranque desde la consola de comandos: o En Windows: /carpetaInstalacion/jboss-as-distribution-6.0.0.20100721-M4/bin/run.bat o en Linux /carpetaInstalacion/jboss-as-distribution-6.0.0.20100721-M4/bin/run.sh Arrancar todos los proyectos que hay en la carpeta de /carpetaInstalacion/jboss-asdistribution-6.0.0.20100721-M4/server/default/deploy. Arranque desde el Eclipse: o Eclipse incluye un plugin con el que se permite interactuar directamente con el servidor desde el propio Eclipse. Si el eclipse que esta utilizando el usuario no lo incluye se puede descargar desde http://www.eclipse.org/webtools/ Para relacionar el Eclipse con Jboss desde Eclipse hay que clickear en New - Server Seleccionar Jboss Esto crear un nuevo proyecto en el workspace llamado server. 127

Bastara con definirle la ruta de instalacin del Jboss y definir los parmetros de la instancia que se quiera arrancar. En la pestaa de Server configuration se puede alternar la instancia:

7.3.3. Jetty
Jetty es un servidor HTTP, adems de un contenedor de servlets. Esta escrito en JAVA y es software libre bajo la licencia Apache 2.0. Jetty es una alternativa a Tomcat por lo que puede ser empotrado dentro del servidor de aplicaciones Jboss. Es muy rpido y eficiente lo que le hace ser un aliciente para muchos proyectos que necesitan la velocidad como un requerimiento. Actualmente Jetty ha sido pasado a la fundacin Eclipse. Esto hace que el servidor y se complemente cada vez mejor con el IDE y los plugins de Maven. Jetty se puede utilizar de varias maneras. Se explican por separado debido a su gran diferencia: Lanzado desde Maven: o Se lanza la ejecucin de un plugin de Maven que arranca el servidor y ejecuta la aplicacin rpidamente. La variable <scanIntervalSeconds>3</scanIntervalSeconds> da la orden de refrescar los cambios en el servidor cada 3 segundos para los cambio en caliente. El fichero de configuracin del plugin es jetty.xml. Donde se especifica el appender que se usa para arrancar jetty. o Arrancar jetty con el plugin de Maven: mvn jetty:start mvn jetty:run o Parar el servidor con el plugin de Maven mvn jetty:stop Lanzado desde consola de comandos: o Se puede arrancar el servidor desde la consola de comando como si se tratara de un fichero .bat o un scripts de Linux. Se deben de cumplir tres cosas para poder utilizar el plugin de Maven: Tener un jetty instalado correctamente en el ordenador. Entrar en la carpeta bin y lanzar run.bat o run.sh Lanzado desde el IDE: o Los IDE se integran con Jetty para as poderle aadirle ms opciones, como son el debugeo o la configuracin en un menu mucho ms sencillo. o Lanzado desde el IDE: Se debe de cumplir las condiciones: Tener un jetty instalado correctamente en el ordenador. Crear un servidor en el IDE, en el apartado de Jboss se explica como hacerlo 128

para Jboss y eclipse. El resto de servidores y IDEs son parecidos, volver a explicarlo sera redundante.

7.4.

SVN

SVN es software libre y cdigo abierto. El inicio de su desarrollo fue por parte de CollabNet en el ao 2000. Es un sistema de control de versiones centralizado. Los SCM ya se comentaron en el apartado de Maven. SVN necesita un repositorio central que contiene las versiones de los ficheros que suben los programadores. Permite recuperar versiones anteriores de los ficheros que estn en el repositorio. SVN guarda un fichero oculto en cada carpeta del fichero. Es un error muy grave modificar estos ficheros o manipular estos ficheros fuera de svn porque pueden perder sus referencias y no funcionar correctamente. Un repositorio de SVN tiene normalmente 3 carpetas/secciones diferentes: El trunk (tronco) es donde se hacen la mayora de los cambios, donde se hace el trabajo diario. Normalmente se le considera inestable en el sentido de que el cdigo no se ha probado o no todas las caractersticas estn implementadas. Tags (etiquetas). Cuando el trunk es estable o se ha llegado a un hito importante se suele crear una etiqueta. Puedes ver las etiquetas como fotos de un proyecto. Una vez tomada es fija, no se deberan hacer cambios. Branches (ramas). Cuando un desarrollador necesita implementar una caracterstica de cierta magnitud que puede interferir demasiado con el trunk pero no quiere hacerlo en local (por ejemplo porque la caracterstica sea implementada en equipo) se puede crear una rama. Al contrario que las etiquetas, los desarrolladores actualizan continuamente las ramas hasta que el problema est resuelto o la nueva caracterstica implementada. Una vez resuelto la rama se fusiona o combina con el trunk. Esos s, SVN es conocido por no combinar ramas muy bien, por tanto se suele evitar. No es el caso de otros sistemas de control de versiones. Las funcionalidades ms importantes de una comunicacin con un repositorio remoto utilizando svn son: Checkout: Obtiene una copia limpia del repositorio. Normalmente se hace una vez por proyecto y por desarrollador. Commit: Sube tus cambios al repositorio. Y por cambios, se hace referencia a cualquier diferencia entre la copia local y el repositorio: agregar/borrar/renombrar archivos o carpetas, modificar ficheros, etc... Cualquier cambio que hagas a tu copia local NO llegar al repositorio hasta que hagas un commit. Add (agregar): Si quieres agregar nuevos ficheros al repo primero hay que hacer un add a traves de SVN. Despus commit. Update (actualizar): Update actualiza tu copia local con los ltimos cambios del repo. SVN intentar combinar o fusionar ficheros cuando sea posible pero puede haber conflictos (ms informacin en la seccin Conflictos). Revert (deshacer cambios): Cuando quieres deshacerte de los cambios locales y obtener una copia limpia del repo.

129

7.5.

Instalacin de las herramientas

El arquetipo instala una aplicacin web que necesita una fuente de datos y un servidor para funcionar. Se van a dar una serie de opciones para que el usuario instale la que ms le guste. Todas son de software libre y cdigo abierto.

7.5.1.

Base de datos

Ha sido necesario instalar una base de datos para desarrollar la aplicacin. Se ha optado por elegir MySQL y Postrgresql ya que son los gestores de bases de datos con ms reputacin dentro del software libre. Aunque se ha probado la aplicacin en ambas bases de datos solo es necesaria instalar una de las dos. 7.5.1.1.

MySQL

Mysql se instala de diferente forma y con diferente software para cada sistema operativo: Linux: Varias distribuciones ya incluyen un Mysql. Si an as es necesario instalarlo se puede hacer desde los repositorios de Linux con la orden: o apt-get install mysql Windows: Se descarga el instalable y se ejecuta. Hay que elegir el usuario administrador y su contrasea y el puerto en el que se quiere que mysql este escuchando. Lo mejor es dejar estos valores por defecto en root y sin contrasea para que no se olvide en un entorno de desarrollo.

7.5.1.2. PostgreSql
Postgresql se instala de diferente forma y con diferente software para cada sistema operativo: Linux: Varias distribuciones ya incluyen un Mysql. apt-get install postgresql Adems de instalar el motor de la base de datos, lo mejor para el mantenimiento, es instalarse un cliente que acte de gestor sobre la base de datos. Se puede utilizar pgadmin3. Para su instalacin hay que escribir los siguientes comandos o sudo apt-get install pgadmin3 Segn la versin del ordenador se instalar una versin de Posgresql, en este caso se ha instalado la: o PostgreSQL 8.4.5 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.4.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3, 64-bit 130

Para entrar en el programa: o sudo su postgres -c psql Una vez dentro hay que ponerle al usuario por defecto la contrasea que se desee: o ALTER USER postgres WITH ENCRYPTED PASSWORD 'postgres'; Se termina creando el usuario que se necesite para el arquetipo que aqu se instala hay que utilizar: o CREATE USER archetype_user WITH ENCRYPTED PASSWORD 'archetype_pwd'; Windows: Se descarga el instalable y se ejecuta. Al instalarlo pide el puerto en el que se va a instalar, el puerto por defecto de Posgresql es 5432. Es importante instalar los drivers como psqlODBC y dems componente de Posgresql como pgAdmin, que es una aplicacin que sirve de gestor de Posgresql.

7.5.2.

IDE

Requisitos obligatorios: JRE de JAVA, recomendada la versin 1.6 Ahora que esta instalado Java y Maven. Se puede empezar a desarrollar el arquetipo. Un IDE apoya mucho al trabajo con los diferentes formatos de fichero que puede haber en un proyecto Maven, las clases JAVA, los ficheros de propiedades, el trabajo con XML. La mejor opcin es elegir uno de los siguientes:

7.5.2.1. Eclipse
Se puede obtener una versin del IDE desde la pgina web de la fundacin en www.eclipse.org. O desde el enlace: Windows: o Se descarga un zip y se descomprime en la carpeta en la que se desee instalar. Linux: o Se descarga un tar y se descomprime en la carpeta en la que se desee instalar.

Es importante seleccionar una carpeta de trabajo. Ya que eclipse se rige en todas sus rutas relativas por este workspace.

7.5.2.2. Netbeans
131

Se puede obtener una versin del IDE desde la pgina web de la fundacin en www.netbeans.org. O desde el enlace: Windows: o Se descarga un zip y se descomprime en la carpeta en la que se desee instalar. Linux: o Se descarga un tar y se descomprime en la carpeta en la que se desee instalar.

Es importante seleccionar una carpeta de trabajo. Ya que eclipse se rige en todas sus rutas relativas por este workspace.

7.5.2.3. Intellij IDEA


Se puede obtener una versin del IDE desde la pgina web de la fundacin en http://www.jetbrains.com/idea/download/index.html. O desde el enlace: Windows: o Se descarga un zip y se descomprime en la carpeta en la que se desee instalar. Linux: o Se descarga un tar y se descomprime en la carpeta en la que se desee instalar.

Es importante seleccionar una carpeta de trabajo. Ya que eclipse se rige en todas sus rutas relativas por este workspace.

7.5.3. aplicaciones

Servidores de

Requisitos obligatorios: JDK de JAVA, recomendada la versin 1.6. Requisitos opcionales: Cualquier IDE del apartado anterior. El fin del arquetipo es crear una aplicacin web, es imprescindible instalarse algn servidor web para que el arquetipo pueda desplegarse en l. Hay varias opciones para la instalacin del servidor web, en esta ocasin hemos elegido tres teniendo en cuenta su gran rendimiento y su bajo requisito de recursos de la mquina.

7.5.3.1. Apache Tomcat


Se descarga el fichero del enlace: http://code.google.com/p/archetypeuma/downloads/detail? name=apache-tomcat-7.0.0.zip Hay que descomprimirlo y moverlo a la carpeta deseada dentro del sistema de ficheros: Las rutas que utiliza Apache Tomcat son relativas a una variable de entorno. Hay que declararla en el sistema operativo: 132

Linux: o export CATALINA_HOME=/home/user/carpetasInstalacion/apache-tomcat-7.0.0 Windows: o set CATALINA_HOME=/C:/carpetasInstalacion/apache-tomcat-7.0.0

7.5.3.2. JBoss AS
Descargar la versin que se desee en http://www.jboss.org/jbossas/downloads/ Se guarda en el sistema de ficheros en una ruta cualquiera ya que para ejecutarlo hay que crear la variable de entorno JBOSS_HOME: En linux: o export JBOSS_HOME=/home/user/carpetasInstalacion/jboss-as-distribution6.0.0.20100721-M4 En windows: o set JBOSS_HOME=/C:/carpetasInstalacion/jboss-as-distribution-6.0.0.20100721M4

7.5.3.3. Jetty
Jetty se puede utilizar de varias maneras. Se explican por separado debido a su gran diferencia: Lanzado desde Maven:

Para lanzar jetty desde Maven hace falta el plugin necesario para que funcione: Maven-jetty-plugin: permite gestionar el servidor Jetty a partir de la lnea de comandos y sin la necesidad de bajarse directamente el servidor Jetty. Aadiendo por consola de comandos: mvn jetty:run es suficiente para arrancar el proyecto y poder utilizarlo con normalidad. <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>Maven-jetty-plugin</artifactId> <version>${Maven-jetty-plugin.version}</version> <configuration> AJAX Push server deployment <jettyConfig>jetty.xml</jettyConfig> <contextPath>/</contextPath> <scanIntervalSeconds>3</scanIntervalSeconds> <scanTargetPatterns> <scanTargetPattern> <directory>src/main/webapp/WEB-INF</directory> <excludes> <exclude>**/*.jsp</exclude> <exclude>**/*.xhtml</exclude> </excludes> <includes> 133

<include>**/*.properties</include> <include>**/*.xml</include> </includes> </scanTargetPattern> </scanTargetPatterns> </configuration> </plugin> Las configuracin detallada del servidor se puede hacer en el fichero jetty.xml <?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <Configure id="Server" class="org.mortbay.jetty.Server"> <!-- Set handler Collection Structure --> <Set name="handler"> <!-- the collection of handlers that will handle the request --> <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection"> <Set name="handlers"> <Array type="org.mortbay.jetty.Handler"> <Item> <New id="WebHandler" class="org.mortbay.jetty.webapp.WebAppContext" /> </Item> </Array> </Set> </New> </Set> <Ref id="WebHandler"> <Set name="contextPath">/archetypeUma</Set> <Set name="war">target/archetypeUma.war</Set> </Ref> </Configure> Hay una restriccin para usar el plugin de Maven: o El plugin se debe de encontrar en un pom.xml catalogado como WAR. Instalacin desde el IDE: Se selecciona el servidor Jetty en el apartado aadir servidor y se referencia a la instalacin del servidor. Instalacin desde la consola de comandos. Hay que instalar el servidor en una carpeta local y meter los war en su carpeta principal.

7.5.4.

SVN

Hay varias aplicaciones que pueden ser de utilizad para establecer relacin con el repositorio. Las ms famosas: Windows: o Se descarga y utiliza la herramienta TortoiseSVN. Hay que bajar e instalar la ltima versin de este software que puede encontrarse en SourceForge 134

Linux: o Algunas distribuciones ya traen integrado un cliente svn como es el caso de Kubuntu que tiene kdesvn ya instalado. o Descargarlo desde consola de comandos con: apt-get install subversion Eclipse: o Descargar e instalar el plugin de subeclipse. La direccin de descarga es: http://subclipse.tigris.org/update_1.6.x o Al iniciar eclipse abrir Help Install new Software Add. o Aadir el nombre y la url de descarga. Al reiniciar ya estar instalado.

Figura X: Instalacin del plugin de Subclipse para eclipse.

135

8. Conclusiones
Se ha expuesto una arquitectura que permite a un equipo de desarrollo, sin conocimiento alguno en creacin de aplicaciones webs, empezar el proyecto con garantas de una arquitectura eficiente, vanguardista y lista para empezar a desarrollar. Existen herramientas muy potentes y trabajadas que ya resuelven un montn de problemas que tienen las aplicaciones webs. Aglutinar todas ellas para hacer una solucin global es un gran paso en el tedioso lo al que la programacin se ha dirigido. Se ha realizado en su plenitud con herramientas de software libre y cdigo abierto. Lo que le aportar a los usuarios innumerables ventajas a la hora del desarrollo y la capitalizacin de los proyectos que se generen a partir de este cdigo. El trabajo de integracin de todos los Frameworks ha sido difcil por tratarse de tecnologas muy novedosa con poca documentacin y casi ningn libro escrito an sobre el tema. El proyecto es actualizable y muy modular, de esta forma si se quiere cambiar el framework Myfaces2 por Struts2 o Hibernate por TopLink, se puede hacer de forma sencilla y se aprovechara la potencia del resto del proyecto. Habra que cambiar las dependencias y configurar los Frameworks que se quisieran instalar. Se ha tenido que descartar Apache CXF para el uso de Web Services conforme se propona en el anteproyecto de fin de carrera. Por las dependencias de algunos de los mdulos de Apache CXF ha versiones anteriores con la que aqu estamos trabajando. La solucin hubiera pasado por crear otro war a parte con las versiones que necesitar pero no nos ha gustado la idea de hacer el proyecto ms complejo porque recortara el nmero de proyectos que empezaran a utilizarlo. Como futura lnea de trabajo habra que ampliar las fuentes de datos que ahora mismo solo son la base de datos y ficheros estticos, amplindola por ejemplo con indexadores, como puede ser Solr de Apache, o con sistemas NOSQL, por ejemplo con Cassandra la que se ha hecho famosa por su uso de Youtube.

136

9. Bibliografa y enlaces
[1] Hibernate in Action (Autores: Chiristian Bauer, Gavin Kink; Edicin: Manning Publications) [2] Maven: The definitive Guide (Autores: Timothy M.O'Brien; Edicin: OReilly Media, Inc, 2008) [3] JAVA2 Manual de usuario y tutorial (Autores: Agustn Froufe; Edicin: RA-MA, Librera y Editorial Microinformtica, Ao 2005 ) [4] Spring Security 3 (Autores: Perter Mularien; Edicin: Packt Publishing, May 26, 2010) [5] The Definitive Guide to Apache MyFaces and Facelets (Autores: Martin Marinschek, Zubin Wadia, Hazem Saleh, Dennis Byrne; Edicin: press; 1 edition (June 2, 2010)) [6] J2EE PATTERNS Best Practices and Design Strategies Prentice Hall; 2 edition (May 10, 2003) [7] http://java.sun.com/ [8] http://Maven.apache.org/ [9] http://Maven.apache.org/download.html [10] http://www.eclipse.org [11] http://www.eclipse.org/webtools/ [12] http://www.netbeans.org [13] http://www.netbeans.org/download/books/definitive-guide/index.html [14] http://www.jetbrains.com/idea/ [15] http://www.jboss.org/ [16] http://tomcat.apache.org/ [17] http://jetty.codehaus.org/jetty/ [18] http://javaserverfaces.java.net/nonav/rlnotes/2.0.0/index.html [19] http://jcp.org/aboutJava/communityprocess/edr/jsr314/index2.html [20] http://myfaces.apache.org/core20/index.html [21] http://www.primefaces.org/ [22] http://static.springsource.org/spring-security/site/reference.html [23] http://www.hibernate.org/ [24] http://dev.mysql.com/doc/refman/5.0/es/index.html [25] http://www.webestilo.com/mysql/ [26] http://www.postgresql.org [27] www.junit.org [28] http://www.jmock.org [29] http://jakarta.apache.org/jmeter [30] http://wiki.apache.org/jakarta-jmeter/ [31] http://www.springsource.org/documentation [32] http://jakarta.apache.org/log4j/ [33] http://code.google.com/intl/es-ES/ [34] http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA [35] https://archetypeuma.googlecode.com/svn/trunk/ [36] https://archetypeuma.googlecode.com [37] http://www.proactiva-calidad.com/java/patrones/index.html [38] http://www.comusoft.com/modelo-vista-controlador-definicion-y-caracteristicas 137

[39] http://www.proactiva-calidad.com/java/patrones/mvc.html [40] http://es.wikipedia.org/wiki/Plain_Old_Java_Object [41] http://es.wikipedia.org/wiki/Framework [42] http://java.ciberaula.com/articulo/diseno_patrones_j2ee/ [43] http://www.slideshare.net/joedayz/spring-inyeccin-de-dependencias [44] http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_Control [45] http://es.wikipedia.org/wiki/Inyecci%C3%B3n_de_dependencias [46] http://www.eclipse.org/articles/article.php?file=Article-Eclipse-and-Maven2/index.html [47] http://java.sun.com/developer/technicalArticles/J2EE/webapp_3/ [48] http://es.wikipedia.org/wiki/Mapeo_objeto-relacional [49] http://www.slideshare.net/joedayz/spring-inyeccin-de-dependencias [50] http://jonysberg.wordpress.com/category/hibernate/ [51] http://www.developersbook.com/spring/interview-questions/spring-interview-questionsfaqs.php [52] http://static.springsource.org/spring/docs/3.0.x/reference/

9.1.

ndices de figuras

1. Diagrama de secuencia del patrn MVC. [39] 2. Ciclo de vida de Maven 3. [46] 3. Ciclo de vida de Hibernate. [50] 4. Ciclo de vida de JSF 2. [47] 5. Divisin de los 3 mdulos de Primefaces. [21] 6. Representacin del componente Men de Primefaces. 7. Insercin en Jmeter de un Grupo de Hilos. 8. Insercin en Jmeter de un Ver Resultados en rbol. 9. Esquema de los mdulos de Spring. [49] 10. Esquema general de la arquitectura. 11. Representacin de los paquetes generados por el arquetipo. 12. Creacin del proyecto en Google Code. 13. Repositorio svn del proyecto en Google Code. 14. Creacin del proyecto en Eclipse. 15. Creacin del proyecto svn en Eclipse. 16. Los diferentes apartados de Google Code en el proyecto. 17. Estructura del proyecto que genera el arquetipo. 18. Caso de uso en el arquetipo 19. Incluir un nevo mdulo o plugin a Netbeans. 20. Incluir el proyecto Maven en Netbeans. 21. Carpetas de Intellij IDEA 22. Vista del espacio de trabajo de Intellij IDEA 23. Estructura de carpetas de Apache Tomcat. 24. Estructura de carpetas de Jboss AS. 25. Instalacin del plugin de Subclipse para eclipse

9.2. ndices de tablas


1. 2. 3. 4. 5. Patrones de la capa de presentacin. Patrones de la capa de negocios. Patrones de la capa de integracin. Estructura de carpetas de un proyecto Maven. Plugin ms utilizados de Maven. 138

6. Comandos ms importantes de Maven. 7. Componentes de JSF 2. 8. Nmero de invocaciones a los Mock. 9. Argumentos a los objetos Mock. 10. Mtodos que representan las devoluciones de objetos Mock. 11. Dependencias del arquetipo.

139

S-ar putea să vă placă și