Вы находитесь на странице: 1из 190

UNIVERSIDADAUTNOMADELESTADODEHIDALGO

INSTITUTODECIENCIASBSICASEINGENIERA CentrodeInvestigacinenTecnologasdelaInformacinySistemas

DesarrollogildeAplicacionesWebconGrailsFramework. Casodeestudio:PROMEPUAEH

MONOGRAFA
Paraobtenerelttulode LICENCIADOENSISTEMASCOMPUTACIONALES

Presenta: P.L.S.C.ALEJANDROGARCAGRANADOS

Asesor: M.C.C.EDUARDOCORNEJOVELZQUEZ

MineraldelaReforma,Hidalgo,enero2012

EstetrabajosedesarrollenelreadeSistemasdeInformacinde la Direccin de apoyo PROMEP dependiente de la Coordinacin de InvestigacinyPosgradodelaUniversidadAutnomadelEstadode Hidalgo;bajoladireccindelM.C.C.EduardoCornejoVelzquez. Lasversionespreliminaresdeestedocumentoyeltrabajoprctico desarrollado han sido utilizados en el taller Desarrollo gil de aplicaciones con Groovy & Grails, as como en la ponencia Desarrollo Web con Grails Framework durante la celebracin del Congreso Universitario en Tecnologas de Informacin y Comunicaciones2011.Porotrolado,alumnosdeoctavosemestrede laLicenciaturaenSistemasComputacionaleshansidointroducidos enelusodeGrailsenlamateriadeBasesdeDatosIIusandoeste documento como referencia, teniendo gran aceptacin entre los mismos.Yfinalmente,alumnosquecursanlasmateriasdeProyecto deFindeCarreraIyIIhancomenzadoatrabajarensuproyectos terminalesempleandoestedocumentocomomaterialdereferenciaal encontrarsedesarrollandoaplicacionesconGrails.

II

Agradecimientos

Agradecimientos
Antesquenadie,quieroagradecerinfinitamenteamifamiliaporel apoyo y amor incondicional que siempre me han brindado. Oscar, Guillermina,OscaryClaudia,estetrabajoesparaustedes. Asimismo, agradezco al M. C. C. Eduardo Cornejo Velzquez por sus enseanzas, consejos y asesoras en el desarrollo de ste documento;perosobretodo,suamistad. Finalmente, quiero agradecer a Alejandra Gmez Varela, mi compaeradeviaje,porlacomprensinysobretodolainspiracin paralarealizacindeesteproyecto.

AlejandroGarcaGranados.

III

Contenido
Agradecimientos.......................................................................III Parte1.Introduccin..................................................................1
Captulo1.Introduccinaldocumento.............................................2
1.1Losinicioseneldesarrollodeaplicacionesweb.........................................2 1.2DefinicindelProblema............................................................................4 1.3Justificacin.............................................................................................4 1.4ObjetivoGeneral.......................................................................................5 1.5ObjetivosEspecficos................................................................................5 1.6Metodologa..............................................................................................6 1.7Herramientastecnolgicas........................................................................7 1.8Descripcindeltrabajo.............................................................................7

Captulo2.Requerimientos,anlisisydiseodelSistemade ControlySeguimientodeIndicadoresPROMEPUAEH(CSI).............10
2.1PROMEP.................................................................................................10 2.2Requerimientos.......................................................................................11 2.2.1Administracindecorrespondencia.................................................12 2.2.2Seguimientodeindicadores.............................................................15 2.2.3Tablerodecontrol............................................................................17 2.2.4Seguimientodeevaluacionesdecuerposacadmicos.......................19 2.2.5Seguimientodeparticipacinenconvocatorias................................20 2.3Anlisis..................................................................................................20 2.3.1Modeladodeentidades....................................................................21 2.3.2Modeladodeprocesos......................................................................21 2.4Diseo....................................................................................................22 2.4.1Capadelgicadenegocios..............................................................22 2.4.2Capadecontrol...............................................................................23 2.4.3Capadepresentacin......................................................................23 2.4.4Diagramadelaarquitecturade3capas..........................................24 2.5Resumen................................................................................................25

Parte2.IntroduccinaGrails...................................................26
Captulo3.PorquGrails?...........................................................27
3.1Eliniciodetodo:EllenguajedeprogramacinJava................................27 3.2JavaEnterpriseEdition..........................................................................29 3.3Latecnologabase:Servlets....................................................................30 3.4Frameworks:encapsuladoyabstraccindefuncionalidad.......................31 3.5FacilitandoJEE:SpringFramework........................................................32 3.6PersistenciaOrientadaaObjetos:HibernateFramework.........................33 3.7Laevolucinnatural:LenguajedeprogramacinGroovy.........................35

IV

3.8Descubriendoelgrial:Grails..................................................................36 3.8.1ConvencinsobreConfiguracin......................................................37 3.8.2Filosofagil...................................................................................38 3.8.3Fundamentosslidos......................................................................38 3.8.4PlantillasyScaffolding..................................................................38 3.8.5IntegracinconJava.......................................................................39 3.8.6Wetware..........................................................................................39 3.8.7Productividad..................................................................................40 3.9Resumen................................................................................................40

Captulo4.Creacinyarranquedelsistema..................................41
4.1Generacindelaaplicacin.....................................................................41 4.2Lgicadenegocios:creacindelasclasesdedominio.............................45 4.3Interaccinconelmundoexterior:controladoresyvistas........................47 4.4Persistencia:almacenamientodedatosenGrails....................................53 4.5Resumen................................................................................................60

Parte3.FundamentosBsicosdeGrails....................................61
Captulo5.Dominiodeunaaplicacinweb...................................63
5.1Creacindeunaclasededominio...........................................................63 5.2Adicindeatributos...............................................................................64 5.2.1Tiposdeatributos...........................................................................65 5.3Consistenciaeintegridad:validacindedatos........................................67 5.4Estilizandolabasededatos....................................................................70 5.5Relacionesentreclasesdedominio.........................................................74 5.5.1Relacinunoauno..........................................................................74 5.5.2Relacinmuchosauno...................................................................75 5.5.3Relacinunoamuchos...................................................................76 5.5.4Relacinmuchosamuchos.............................................................78 5.6Resumen................................................................................................79

Captulo6.ModeloObjetoRelacionalenGrails(GORM)..................80
6.1HibernateFrameworkyORM..................................................................80 6.2ORMenGrails........................................................................................82 6.3Mtodoscomunesatodaslasclasesdedominio.....................................83 6.3.1Create.............................................................................................83 6.3.2Read...............................................................................................84 6.3.3Update............................................................................................85 6.3.4Delete..............................................................................................85 6.4Mtodosdinmicos.................................................................................86 6.5Realizacindeconsultasorientadasaobjetos:Criteria...........................88 6.6HibernateQueryLanguaje(HQL)............................................................91 6.7Resumen................................................................................................92

Captulo7.CapadepresentacinWeb:ControladoresyGroovy ServerPages...................................................................................93
7.1Generacindecontroladores...................................................................93 7.2Anlisisdetalladodeloscontroladores....................................................94 7.2.1indexylist.......................................................................................94 7.2.2create..............................................................................................96 7.2.3save.................................................................................................97 7.2.4show...............................................................................................99 7.2.5edit................................................................................................100 7.2.6update...........................................................................................101 7.2.7delete.............................................................................................104 7.3Generacindelasvistas........................................................................106 7.4Plantillasusadasparalageneracindecontroladoresyvistas...............107 7.5GroovyServerPages..............................................................................109 7.6Expresiones..........................................................................................109 7.7Taglibs...................................................................................................111 7.7.1Tomadedecisiones.........................................................................111 7.7.2Iteraciones.....................................................................................112 7.7.3ElementosHTML............................................................................114 7.7.3.1Formularios............................................................................114 7.7.3.2Camposdetexto......................................................................116 7.7.3.3Listasdesplegables..................................................................117 7.7.3.4Elementosdeseleccin...........................................................118 7.7.3.5Cargadearchivos....................................................................119 7.7.3.6Vnculosyrecursosestticos..................................................120 7.7.4Tablas............................................................................................121 7.7.5Manejodeerroresenclasesdedominio..........................................122 7.7.6Formatodedatos...........................................................................123 7.7.7Usodevariables.............................................................................124 7.8IncorporandoWeb2.0medianteAjax....................................................125 7.8.1g:remoteLink..................................................................................127 7.8.2g:remoteField.................................................................................128 7.8.3g:remoteFunction...........................................................................129 7.8.4g:formRemote.................................................................................130 7.8.5g:submitToRemote.........................................................................130 7.9Resumen...............................................................................................131

Parte4.TpicosavanzadosdeGrails.......................................132
Captulo8.DesarrollodeAPI'stipoRESTconGrails....................133
8.1QueesunAPI?....................................................................................133 8.2ArquitecturaREST................................................................................134 8.3ImplementacindeunAPItipoREST....................................................135 8.4ExperimentandoconelAPI...................................................................140 8.5SeguridadenAPI'stipoREST................................................................142 8.6Ejemplodelavidareal:elAPIdeTwitter...............................................142

VI

8.7Resumen..............................................................................................144

Captulo9.Plugins.......................................................................145
9.1IntroduccinalospluginsdeGrails......................................................145 9.2Creacindinmicademens................................................................146 9.3Exportacindedatosadiversosformatos..............................................149 9.4UsodetablasdinmicasconJQGrid....................................................152 9.5AdicindeSeguridadmedianteSpringSecurity....................................155 9.6Ingenierainversadebasesdedatos.....................................................160 9.7Inclusindeotrospluginsenelsistema................................................162 9.7.1UsodecalendariosconelpluginCalendar.....................................162 9.7.2DesplieguedeayudamedianteHelpBallons..................................163 9.7.3GeneracindinmicadegrficasconGoogleChartyjQuery..........164 9.8Resumen..............................................................................................167

Conclusionesyperspectivasafuturo.......................................168 Glosariodetrminos...............................................................170 Bibliografa..............................................................................174 AnexoA:InstalacindeGrails.................................................179


Prerrequisitos................................................................................179 Listadepasosaseguir.................................................................179

AnexoB:DiagramadeEntidadesdelSistema(CSI)dePROMEP UAEH......................................................................................181

VII

ndicedeFiguras
Figura1:ActividadesdelDirector..........................................................................14 Figura2:ActividadesdelaRecepcionista...............................................................14 Figura3:ActividadesdelTrabajador......................................................................15 Figura4:ActividadesdelAdministrador.................................................................15 Figura5:DiagramadeArquitecturade3capasutilizadaporGrails.......................25 Figura6:Pginainicialdelaaplicacin.................................................................44 Figura7:Pginainicialdelaaplicacinconunvnculoalcontrolador...................49 Figura8:PantallaprincipaldelcatlogodeProfesores...........................................50 Figura9:Pginadecreacinderegistros...............................................................50 Figura10:Confirmacindelacreacindelregistro................................................51 Figura11:Formulariodeedicindedatos...........................................................102 Figura12:RespuestadelservidoralinvocarlaaccinlistdelAPIREST...............138 Figura13:Respuestadelservidorconelmtodoshow.........................................139 Figura14:Respuestadelservidorconelmtodoshowconunisbninvlido.........140 Figura15:PluginPosterparalacreacindepeticionesHTTP................................141 Figura16:PginaprincipaldelAPIdeTwitter......................................................143 Figura17:RespuestadelAPIdeTwitteralsolicitareltimelinepblico..................144 Figura18:Mengeneradoporelplugin"navigation"............................................147 Figura19:Aspectodelmenalhacermodificaciones...........................................148 Figura20:Barradeexportacindedatos.............................................................151 Figura21:Reportegeneradoporelpluginexport.................................................151 Figura22:TablaconJQGridyAjax.....................................................................155 Figura23:SolicituddecredencialesconSpringSecurity......................................158 Figura24:PginadeiniciodesesindelaaplicacinGrailsdePROMEPUAEH...159 Figura25:PantallaprincipalparaunusuariotipoDES.......................................160 Figura26:Usodelplugincalendar......................................................................163 Figura27:Usodelpluginhelpballons.................................................................164 Figura28:UsodeGoogleChartyjQueryparalavisualizacindegrficas...........165 Figura29:UsodeGoogleChartparalageneracindegrficasdeindicadores.....166

VIII

ndicedeTablas.
Tabla1:Indicadoresdedesempeo........................................................................16 Tabla2:TiposdedatossoportadosporGrails........................................................66 Tabla3:RestriccionesutilizadasenGrails.............................................................69 Tabla4:RestriccionesutilizadasenGrails(continuacin)......................................70 Tabla5:Algunasconvencionesutilizadasenlageneracindelabasededatos......71 Tabla6:AlgunasopcionesdeestilizacindelabasededatosenGrails..................72 Tabla7:Parmetrosdelmtodosave......................................................................83 Tabla8:ComparadoresyOperadoressoportadosporlosmtodosdinmicos.........87 Tabla9:ComparadoresyOperadoressoportadosporlosmtodosdinmicos (continuacin).......................................................................................................88 Tabla10:MtodossoportadosporCriteria.............................................................90 Tabla11:MtodosenGrailsparaelusodeHQL....................................................91

IX

Parte1.Introduccin

Parte1

Introduccin

En la Parte 1 del presente trabajo se introduce al lector en el panoramageneraldelatemticaplanteadaeneldocumento. Enel Captulo1 sedaunaintroduccinalcontextohistricodel desarrollodeaplicacionesweb,seexplicalaproblemticaasociada,se plantean los objetivos tanto general como especficos, justificacin, metodologa y herramientas tecnolgicas. Al final se presenta un mapageneraldelcontenidotratadoalolargodeldocumento. EnelCaptulo2:Requerimientos,anlisisydiseodelSistemade Control y Seguimiento de Indicadores PROMEPUAEH (CSI), se presentanlasnecesidadesdeladireccindePROMEPUAEHparala realizacin de una aplicacin web. Se hace un anlisis de estos requerimientosyposteriora steserealizaundiseopreliminardela aplicacin.

Captulo1.Introduccinaldocumento

Captulo1

Introduccinaldocumento

Todotrabajorequieredeunaexplicacinintroductoriaqueempape al lector en el panorama general del mismo. En este captulo se describen de forma general los principales lineamientos de este documento.

1.1

Losinicioseneldesarrollodeaplicacionesweb

LaWorldWideWeb(WWW),oloqueseconocecomnmentecomo Internet, apareci en los inicios de la dcada de los 90's. Las computadoras comenzaron a comunicarse entre s desde cualquier partedelmundo;elintercambiodedatosnosolopodahacerseanivel local, sino que una persona que viva en Amrica poda enviar las fotosdesubodaaunamigoradicadoenAsiacasialmismotiempoen el que las fotografas eran tomadas. Las posibilidades tecnolgicas comenzabanasobrepasarsuslmites,generandoasunnuevocampo enelmbitodelainformtica:seiniciabalaredderedes. Acasi20aosdesurgimientodeInternet,esevidentesuevolucin, impactoeinfluenciaenlavidadelaspersonas.Anteseraimpensable hacercompras,transaccionesbancarias,cursosacadmicosyforos dediscusinatravsdeunareddecomputadoras.Hoyenda,las redessocialescomoTwitteryFacebookgobiernanloshbitosdiarios delosjvenes(ynotanjvenes)[PRE01];sitioscomoAmazon,eBayy MercadoLibrepropicianlacomprayventadeunsinfndeproductos yservicios;dentrodepocosaostodalafacturacinserealizar de maneraelectrnica;elCloudComputing(CmputoenlaNube)est

Captulo1.Introduccinaldocumento

incitando la migracin de aplicaciones de escritorio y sistemas operativos a la red. Las tecnologas computacionales tienen una mayor aceptacin conforme stas se involucran en las actividades diariasdelagente. La demanda de los usuarios de Internet ha crecido de forma exponencial en los ltimos 10 aos. En un mundo cuyo ritmo de trabajo es tan vertiginoso y cambiante, los sitios web necesitan generarse y ponerse en lnea tan pronto como sea posible. Los desarrolladores de software han visto la necesidad de generar diversas herramientas de creacin de aplicaciones informticas, las cualeshancubiertoenciertamedidalanecesidaddeldesarrollo gil de aplicaciones. Sin embargo, muchas de estas herramientas o frameworks involucran al programador en muchas tareas de configuracinajenasalasnecesidadesorequerimientosquesusitio webnecesita,haciendolentoelprocesodedesarrolloyretrasandola codificacindelaspartespropiasyespecficasdesuaplicacin. Lamayoradelasaplicacioneswebrequierenunprocesoinicialde desarrollobastanterepetitivo,porloquelaautomatizaci ndedicho procesopuedeahorrarsemanaseinclusomesesdetrabajoatodoun equipo de programadores, permitindoles concentrarse en otros aspectosquesonpasadosporaltodurantelafaseinicialdelproyecto debidoacuestionesdetiempoounamalaplaneacin. Estedocumentointroduceallectoraldesarrollogildeaplicaciones webmedianteelusodeGrails [GRA01],unaherramientaqueagiliza muchasdelastareasdeconfiguracinydesarrollodeunaaplicacin

Captulo1.Introduccinaldocumento

web.Grailsest ganandomuchosseguidoresconformeevolucionay demuestrasurobustez,estabilidadysobretodo,facilidaddeuso.

1.2

DefinicindelProblema

La demanda de aplicaciones en Internet ha crecido de forma desmesuradaenlosltimos10aos.Lossitioswebnecesitanponerse en lnea lo ms pronto posible. La filosofa Agil de Desarrollo de Software[AAL01]harespondidoconmtodos,tcnicasyherramientas que satisfacen tal demanda. Aunado a esto, la mayora de las aplicacioneswebactualessiguenunprocesosimilaraliniciodesu implementacin. La automatizacin de estos pasos permite al desarrolladorconcentrarseenlosaspectosquesonnuevosparasu aplicacin. Grails permite la agilizacin y automatizacin del desarrollodeaplicacioneswebdeformarpidaytransparente.

1.3

Justificacin

Grails es una herramienta que permite el desarrollo gil de aplicaciones y reduce el tiempo de entrega. La documentacin existenteparadichoframeworkest disponibleeninglsyhaypoca informacin en espaol. Asimismo, el acercamiento de las universidadesenMxicocondichaherramientaescasinulo,porlo que es importante contar con un documento de referencia para comenzar a utilizarla. Los estudiantes, programadores y desarrolladores de aplicaciones web se ven beneficiados con este documentoconunaltoniveldeproductividad,estabilidad,robustezy fcilmantenimientodesussistemasdesarrolladosenGrails.

Captulo1.Introduccinaldocumento

1.4

ObjetivoGeneral

Describirlosfundamentosdeldesarrollo gildeaplicacionesweb medianteelusodeGrailsFrameworkparaimplementarelSistemade ControlySeguimientodelosIndicadoresEstrat gicosdelPrograma delMejoramientodelProfesorado(PROMEP).

1.5

ObjetivosEspecficos
DescribirlosfundamentosdeGrailsmedianteelanlisisdela estructuradelosproyectosyloscomponentesdelosmismos para la implementacin gil de aplicaciones web robustas y portables.

Comprender las ventajas y desventajas del desarrollo gil de aplicaciones.

Visualizar la aplicacin de Grails mediante el estudio de un casoprcticoimplementadoenlaDireccindePROMEPUAEH.

Modelar las entidades de un sistema mediante clases de dominio.

Conocer el paradigma ORM (ObjectRelational Mapping) y su implementacinenGrails.

Aplicar la tecnologa GSP (Groovy Server Pages) para el desarrollodepginaswebdinmicas.

ImplementarAPI'stipoRESTparalaexposicinyaccesoremoto dedatos.

Captulo1.Introduccinaldocumento

Utilizar complementos (plugins) para exponenciar la velocidad dedesarrolloenunaaplicacinweb.

1.6

Metodologa

La metodologa utilizada para la redaccin del documento est basada en la serie de libros Deitel & Deitel [DEI07], denominada Mtodologa de cdigo activo. sta consiste en explicar un poco de teoraacercadeuntpicoyvisualizarsuaplicacinpormediodeun fragmentodecdigo. Para la implementacin del caso prctico en la Direccin de PROMEPUAEH, se usa una mezcla de diversas metodologas de desarrollodesoftware,entrelascualesdestacan: SCRUM [SCR01], metodologa basada en una tcnica de rugby ampliamente utizada en entornos de desarrollo gil [PRE02]. Modelo Incremental, otra metodologa gil que entrega artefactos parciales de software en lapsos determinados de tiempo[PRE03][IAN05]. Modelo en Cascada, una de las primeras metodolog as empleadaseneldesarrollodesoftwareyquerepresentala basedelagranmayoradeellas[PRE04]. Desarrollodirigidoporcaractersticas,elcualsebasaenla modularidad de los requisitos del software que se pueden entregaren2semanasomenos[PRE05].

Captulo1.Introduccinaldocumento

1.7

Herramientastecnolgicas

LaherramientatecnolgicautilizadaenestedocumentoesGrails, unsoftwaregratuitoydecdigoabiertoqueasuvezest basadoen lassiguientestecnologas: SpringFramework [SPR01],diseadoparafacilitarelusode laplataformaJavaEnterpriseEdition(seccin3.5). HibernateFramework[HIB01],creadoparaelusodebasesde datosrelacionalesmedianteelparadigmadelaProgramacin OrientadaaObjetos(seccin3.6). Lenguaje de Programacin Groovy [GRO01], un lenguaje dinmicobasadoenJava,Ruby,PythonySmalltalk(secci n 3.7) Al ser un framework basado en Groovy, Grails requiere la instalacindelKitdeDesarrollodeSoftwaredeJava(JDK,porsus siglaseningls).ElJDKcontienelamquinavirtualdeJava(JVM)y todaslasbibliotecasdeclasesnecesariasparalacorrectaejecuci n de aplicaciones. El Anexo A: Instalacin de Grails, contiene las instruccionesnecesariasparaladescargaeinstalacindelJDKyde Grails.

1.8

Descripcindeltrabajo

Elpresentetrabajoestdivididoen4partes: Parte1:Introduccin. Parte2:IntroduccinaGrails.

Captulo1.Introduccinaldocumento

Parte3:FundamentosBsicosdeGrails. Parte4:TpicosavanzadosdeGrails.

La Parte 1 es una introduccin al documento. Se plantea la problemtica encontrada en el desarrollo de aplicaciones web y se proponeunasolucinmedianteelusodeGrails.Asimismo,sedana conocerlosrequerimientosdelsistemadesarrolladoenlaDireccinde PROMEPUAEH. La Parte 2 introduce al lector a Grails. Se habla acerca de los frameworks antecesores que motivaron su creacin, sus ventajas y desventajasrespectoaotrasherramientasdedesarrollo.Asimismo,se iniciaeldesarrollodelaaplicacinwebrequeridaenPROMEPUAEH parasuadministracininterna.Estaaplicacinesutilizadaalolargo de todo el documento como referencia para la explicacin de los diversostemastratados. La Parte 3 cubre las bases de Grails: Clases de Dominio, que modelan las entidades obtenidas en el proceso de diseo de un proyecto de software; el paradigma ObjectRelational Mapping en Grails (GORM, por sus siglas en ingls), una tecnologa basada en Hibernate que permite manejar la persistencia de las clases de dominio; asimismo, se habla de Groovy Server Pages (GSP), una herremientasimilaraJavaServerPages(JSP)peroconcapacidades superioresymssencillasdeutilizar. La Parte4 abarcaalgunostemasavanzadoseneldesarrolloweb con Grails. Se explica el tratamiento de API's de tipo REST con la

Captulo1.Introduccinaldocumento

nomenclaturaXML,tecnologautilizadaparalaconexineinteraccin dediversasaplicaciones.ParacerrarelestudiodeGrails,seintroduce allectoraunadelascaractersticasmspoderosas:elusodeplugins. Dichoscomplementostienenfuncionalidadesmuyvariadasquevan desdelaexportacindetablasadiversosformatoshastalaingeniera inversa de bases de datos existentes desde diferentes DBMS. Asimismo,sedescribelaimplementacinfinaldelcasoprcticodela DireccindePROMEPUAEHintroducidoenel Captulo2.Endicha institucin se generaron aplicaciones web y se integraron bases de datosexistentesaGrails.Enestecasodeestudioseutilizagranparte delcontenidodescritoenloscaptulosanteriores. Finalmente, se dan a conocer las conclusiones acerca del documentoylasperspectivasafuturoacerca deldesarrollo gilde aplicaciones con Grails. Adems, se incluye un anexo que describe pasoapasoelprocesodedescargaeinstalacindelJDKydeGrailsy un anexo que muestra el diagrama de entidades generado para el ejemploprctico.

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Captulo2 Requerimientos, anlisis y diseo del Sistema de Control y Seguimiento de Indicadores PROMEPUAEH(CSI)
LadireccindePROMEPUAEHmanejaunagrancantidaddedatos einformacin.Enalgunosprocesos,elmanejodelainformacinsin ayuda de la tecnologa se vuelve una tarea difcil, por lo que es necesario llevar a cabo el desarrollo de aplicaciones que faciliten dichosprocesos.Enestecaptulosedescribenlosrequerimientosde stos,ascomoelanlisisydiseocorrespondiente.

2.1

PROMEP

De acuerdo a [PRO01], el Programa de Mejoramiento del Profesorado(PROMEP)estdirigidoaelevarpermanentementeelnivel de habilitacin del profesorado, con base en los perfiles adecuados para cada subsistema de educacin superior. Se busca que al impulsar la superacin permanente en los procesos de formacin, dedicacin y desempeo de los cuerpos acadmicos de las instituciones,seelevelacalidaddelaeducacinsuperior. El PROMEP responde a los propsitos del Programa Sectorial de Educacin 20072012, que establece como uno de sus objetivos estratgicos: "Elevar la calidad de la educacin para que los estudiantesmejorensuniveldelogroeducativo,cuentenconmedios parateneraccesoaunmayorbienestarycontribuyanaldesarrollo nacional, y como objetivo particular: "Fortalecer los procesos de

10

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

habilitacinymejoramientodelpersonalacadmico". Paralograrsucometido: Otorga becas nacionales y para el extranjero a profesores de carrera de las universidades pblicas, para la realizacin de estudiosdeposgradoenprogramasdereconocidacalidad. Apoyalacontratacindenuevosprofesoresdetiempocompleto que ostenten el grado acadmico de maestra o de doctorado (preferentemente)ylareincorporacindeexbecariosPROMEPa su institucin despus de haber terminado sus estudios en tiempo dotndolos con los elementos bsicos para el trabajo acadmico. ReconoceconelPerfilDeseableaprofesoresquecumplen,con eficacia y equilibrio sus funciones de profesor de tiempo completo, como atender la generacin y aplicacin del conocimiento,ejercerladocenciayparticiparenactividadesde tutorasygestinacadmica. ApoyaelfortalecimientodeCuerposAcadmicos,laintegracin de redes temticas de colaboracin de Cuerpos Acadmicos, incluyendo el apoyo para gastos de publicacin y becas Post Doctorales.

2.2

Requerimientos

Antesdeescribircualquierlneadecdigo,antesdeaventurarsea

11

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

disearunapginaweb,unainterfazgrficadeescritorioounabase de datos, es indispensable saber qu es lo que se necesita. La direccindePROMEPUAEHpresenta3requerimientos: Laadministracindelacorrespondenciaentrante. El seguimiento de indicadores y evaluaciones de cuerpos acadmicos. La realizacin de un tablero de control de los indicadores vinculadosaobjetivosestratgicosdelainstitucin. Lassiguientesseccionesdetallanlosrequerimientosdecadapunto. 2.2.1 Administracindecorrespondencia Diariamente, la direccin de PROMEPUAEH recibe correspondenciaremitidadesdediversospuntosquevandesdeoficios manejadosdentrodelamismaUniversidadhastapaquetesenviados desdedistintaszonasdelaRepblicaMexicana. Esteprocesorequieredelaparticipacindevariaspersonasycada unadeellasdesarrollaactividadesquedebenserapoyadasparalo siguiente: Una persona con el rol de recepcionista recibe la correspondencia y la debe hacer llegar a su respectivo destinatariodeformaeficienteyeficaz. Eldirectordel readebetenerunmejorcontrol,seguimiento ysupervisindelacorrespondenciarecibidayemitida.

12

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Elpersonaldebedaratencin,seguimientoyconsultadela correspondenciaquelehasidoasignada.

Para el caso de la correspondencia recibida por parte de instanciaspropiasdelaUniversidad,losprofesoresylderes decuerposacadmicosdebendeconocerelestadoenquese encuentransussolicitudespresentadas.

Parasistematizaryautomatizaresteprocesoserequieredesarrollar eimplementarunanuevaaplicacinbasadaenWebaccesibledesde cualquiercomputadoraconaccesoaInternet.Dichaaplicacindebe tenerlasiguientefuncionalidad: Que un usuario con el rol de recepcionista reciba la correspondenciayregistresualtaenelsistema. Otro usuario con el rol de director debe asignar la correspondenciaasudestinatariocorrespodiente. Elusuariodestinatario,quepuedetenercualquierrol,recibela correspondenciaydecidequhacerconella: Si ha recibido la correspondencia pero an no la ha atendido,debeactualizarelestadodelacorrespondenciaen elsistemacomoEnEspera. Siharecibidoyatendidolacorrespondencia,debeactualizar el estado de la correspondencia en el sistema como Terminado.

13

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Elusuarioadministrador,eldirectoryelrecepcionistapueden consultarellistadodecorrespondenciadetodoslosusuarios, mientras que el resto nicamente puede visualizar su propia correspondencia.

Elusuarioadministradorpuederealizarcualquieroperacin.

Las figuras 1, 2, 3 y 4 muestran los casos de uso de los roles requeridosenlaaplicacinysusactividadescorrespondientes.

Figura 1: Actividades del Director.

Figura 2: Actividades de la Recepcionista.

14

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Figura 3: Actividades del Trabajador.

Figura 4: Actividades del Administrador.

2.2.2 Seguimientodeindicadores DentrodeladireccindePROMEPUAEHsecuentaconelSistema InstitucionalparaelSeguimientoAcadmicoyCientficodelaUAEH (SISAC) [COR07], a travs del cual se concentra, administra y

15

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

distribuye toda la informacin relacionada con la capacidad acadmica y produccin cientfica y acadmica de los profesores y cuerpos acadmicos de la UAEH. Uno de los aspectos manejados dentrodelSISACeselusodeindicadoresdedesempe o,loscuales permitenvisualizardeformacuantitativaelcomportamientoactual. Los indicadores de desempeo que deben ser administrados se muestranenlaTabla1.
Indicador PTC con posgrado % PTC con posgrado PTC con doctorado % PTC con doctorado PTC con perfil % PTC con perfil PTC en SNI % PTC en SNI CA consolidados % CA consolidados CA en consolidacin % CA en consolidacin PTC en CA % PTC en CA CLCULO PTC con posgrado = PTC con maestra + PTC con doctorado % PTC con posgrado = PTC con posgrado / Total de PTC Total de PTC con doctorado % PTC con doctorado = PTC con doctorado / Total de PTC PTC con perfil = Total de PTC con perfil maestra + Total de PTC con perfil doctorado % PTC con perfil = PTC con perfil / Total de PTC Total de PTC en SNI % PTC en SNI = PTC en SNI / Total de PTC Total de CA consolidados % CA consolidados = CA consolidados / Total de CA Total de CA en consolidacin % CA en consolidacin = CA en consolidacin / Total de CA Total de PTC en CA % PTC en CA = PTC en CA / Total de PTC

Tabla 1: Indicadores de desempeo.

Bsicamente, se requiere una aplicacin en lnea que permita realizarlassiguientestareas:

16

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Administracindecatlogosdelossiguientesaspectos: Convocatorias. Indicadores.

Administracindelosusuariosdelaaplicacin. Seguimientodeevaluacionesdecuerposacadmicos. Seguimientodeparticipacinenconvocatorias. Seguimientodelosindicadoresestratgicos. TablerodeControldeindicadoresestratgicos. Generacindereportesendiversosformatos.

La administracin de catlogos se refiere a las 4 operaciones bsicasdeunabasededatos:altas,bajas,modificacionesyconsultas (Create,Read,Update,Delete:CRUD). Uno de los objetivos de la aplicacin es la visualizacin de los indicadores a travs de un tablero de control. Mientras que las pantallas administrativas sirven para manipular la informaci n, el tablero de control muestra una serie de grficas descriptivas relacionadascondichainformacin. 2.2.3 Tablerodecontrol Losindicadoresestratgicosmanejadosenlaaplicacindescritaen la seccin 2.2.2 necesitan reflejar su comportamiento histrico de formagafica,paraqueassepuedaanalizarelcambiodelosmismos

17

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

atravsdeltiempoyas favorecerlatomadedecisionesporpartede losdirectivosanivelinstitucional,asicomoalinteriordelasEscuelas eInstitutos. Deacuerdoa[WIK02]y[KAP99]: El tablero de control (TdeC) es una herramienta, del campo de la administracin de empresas, aplicable a cualquierorganizacinyniveldelamisma,cuyoobjetivoy utilidad bsica es diagnosticar adecuadamente una situacin.Selodefine[sic]comoelconjuntodeindicadores cuyo seguimiento y evaluacin peridica permitir contar conunmayorconocimientodelasituacindesuempresao sectorapoyndoseennuevastecnologasinformticas Losindicadoresestratgicosquedebenserincluidoseneltablero decontrolsonlossiguientes: ProfesoresdeTiempoCompletoconPosgrado. ProfesoresdeTiempoCompletoconDoctorado. ProfesoresdeTiempoCompletoconPerfil. Profesores de Tiempo Completo en el Sistema Nacional de Investigadores. CuerposAcadmicosConsolidados. CuerposAcadmicosenConsolidacin. ProfesoresdeTiempoCompletoenCuerposAcadmicos.

18

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Asimismo, las grficas utilizadas deben reflejar los siguientes aspectos: Unsemforoquemuestreelestadoactualdelindicador. Valoreshistricosdelindicadorenelperodo20002010. Valores absolutos empleados para calcular el indicador en el perodo20002010. Consultar el tablero de control a nivel institucional y de institutos. 2.2.4 Seguimientodeevaluacionesdecuerposacadmicos. El seguimiento de las evaluaciones de cuerpos acadmicos por parte de la coordinacin acadmica del PROMEP nacional es necesarioparaadministrarydistribuirlosdictmenesemitidospor loscomitsevaluadoresdeloscuerposacadmicos.Losdirectivosa nivel institucional y de los institutos deben tener acceso a dicha informacinparaqueseaconsideradaenlosprocesosdeplaneaciny seguimientodeloscuerposacadmicos. Lainformacinquesenecesitamanejares: Nombredelcuerpoacadmico. Aodeevaluacin. GradodeconsolidacinpropuestoporlaUAEH. Gradodictaminadoporelcomitdeevaluacin.

19

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Dictamenrecibido.

2.2.5 Seguimientodeparticipacinenconvocatorias. El seguimiento de la participacin en las convocatorias de profesores y cuerpos acadmicos es necesaria para conocer la participacindeprofesoresycuerposacadmicosenlasconvocatorias emitidasporelPROMEPnacional.Esteseguimientopermiteconocer los niveles de participacin en cada convocatoria por ao de participacin. Serequieremanejarlasiguienteinformacin: Nombredelprofesorocuerpoacadmico. Aodeparticipacin. Convocatoriaenlaqueparticipa. Resultadodelaparticipacin.

Esnecesarioquesehabilitelaconsultaporconvocatoriayao,as comoportipodeparticipante(profesorocuerpoacad mico).Adems, sedebepresentarungrficodescriptivoquemuestreelnmerode participantesporaoenlaconvocatoriasdePROMEPUAEH.

2.3

Anlisis

Una vez obtenidos y entendidos los requerimientos, se procede a realizarelanlisisdelosmismos.Elanlisisdeunsistemaresponde alapreguntaqusenecesita?.Lospasosaseguirsonlossiguientes:

20

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Modeladodeentidades:consisteenlaidentificacindeobjetos del mundo real involucrados en los procesos descritos en los requerimientosparasurepresentacincomputacional.

Modelado de procesos: consiste en la identificacin de las diversasactividadesquerealizanlasentidadestantodeforma individualcomoenconjuntoparalograrelobjetivodelsistema.

2.3.1 Modeladodeentidades Debido a quela direccin de PROMEPUAEHya cuenta con una basededatos,elmodeladodeentidadesseresumeenlaadaptacin de las tablas existentes a la aplicacin. Con base en los requerimientos del sistema, se obtiene una lista de objetos y las relaciones existentes entre s. Los sustantivos que aparezcan en la descripcinsonidentificadoscomoposiblesentidades.Elresultadode steanlisisarrojaeldiagramamostradoenelAnexoB:Diagramade Entidades del Sistema (CSI) de PROMEPUAEH . Existen otras entidades involucradas, pero para los objetivos de las aplicaciones, nicamentesemuestranlasentidadesrelevantes. 2.3.2 Modeladodeprocesos Dada la naturaleza gil de la implementacin del sistema, la descripcinrealizadaenlaseccin2.2essuficienteparacompletarel modeladodeprocesos.

21

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

2.4

Diseo

DadoqueeltemaprincipaldeestedocumentoeselusodeGrails paraeldesarrollodeaplicacionesweb,eldiseodelasaplicaciones requeridas en la direccin de PROMEPUAEH est basado en la arquitectura ofrecida por elframework. Dicha arquitectura utiliza 3 capas: Capadelgicadenegocios. Capadecontrol. Capadepresentacin.

Lassiguientesseccionesexplicanadetallecadaunadeellas. 2.4.1 Capadelgicadenegocios Elncleodeunaaplicacinqueutilizaunaarquitecturade3capas eslalgicadenegocios.Enellasemodelanlasentidadesdelmundo real y se realizan las tareas necesarias para su manipulaci n, tal comosucreacin,almacenadoyactualizacin.Dentrodelentornode Grails, esta capa est representada por las clases de dominio, sus mtodos relacionados con la persistencia y el acceso a la base de datos.Enalgunasaplicacionesmsrobustas,seincluyelacapade servicios,lacualcontrolaelaccesodecualquierprogramaalal gica de negocios, facilitando el mantenimiento y promoviendo la reutilizacindecdigo. GraciasalafacilidadqueofreceGrailsparaelaccesoacualquier

22

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

tipo de base de datos y a la existencia de un plugin de ingenier a inversa de bases de datos (seccin 9.6), la generacin del cdigo correspondientealaestructurabsicadelalgicadenegociosesuna tareaquepuedeautomatizarse. 2.4.2 Capadecontrol Lasaplicacioneswebnecesitanunaformadecomunicacinentrela lgicadenegociosyelresultadofinalmostradoalusuario.EnGrails, lacapadecontroleslaencargadadelograrlainteractividadentrelas clasesdedominio(olosservicios)ylacapadepresentacinatravs de clases controladoras (o controladores, como se maneja en las secciones 7.1 y 7.2).Lacapadecontroltienelahabilidadderecibir peticiones HTTP, procesarlas y emitir un resultado utilizando el mismo protocolo. El contenido puede abarcar desde simples caractereshastacomplejosarchivosmultimedia. TomandocomobaselasclasesdedominiogeneradasporGrails,el comando grails generatecontroller (seccin 7.1) crea por defecto el cdigonecesarioparalainteraccinentreclasesdedominioylacapa depresentacin,porloquelacodificacindelesqueletoinicialdela capa de control, al igual que la capa de negocios, puede automatizarse. 2.4.3 Capadepresentacin En una aplicacin web, el resultado final mostrado al usuario generalmente se representa por medio de interfaces grficas de

23

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

usuario(GUI,porsussiglaseningls)enunnavegadorweb.Lacapa depresentacinenGrailsvienerepresentadaporlatecnologaGroovy Server Pages o GSP (seccin 7.5). La capa de control entrega un modeloqueunarchivoGSPpuedemanipularmediantec digoGroovy (seccin 7.6)oatravsdelusodetaglibs(seccin 7.7).Asimismo,la capa de presentacin se representa por medio de archivos XML (Figura17),textoenformatoJSON,PDF,einclusiveaudioyvideo. TomandocomobaselasclasesdedominiogeneradasporGrails,el comandograilsgenerateviews(seccin7.3)creapordefectoelcdigo HTML y GSP necesarioparalacapadepresentacin,porloquela codificacindelesqueletoinicialdelasinterfacesgrficasdeusuario, aligualquelacapadenegociosyladecontrol,puedeautomatizarse. 2.4.4 Diagramadelaarquitecturade3capas La Figura 5 muestra la interaccin entre la capa de lgica de negocios,lacapadecontrolylacapadepresentacin.Cabedestacar quecadacapatieneconocimiento nicamentedelacapainmediata inferior.Estoquieredecir,porejemplo,quelosserviciosslotienen acceso a las clases de dominio y que la base de datos no tiene conocimientodelascapasqueaccedenaella.

24

Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)

Figura 5: Diagrama de Arquitectura de 3 capas utilizada por Grails.

2.5

Resumen

La direccin de PROMEPUAEH tiene necesidades que pueden solventarse mediante la creacin de aplicaciones web. El anlisis y diseo presentados en este captulo sirven como base para la generacinypuestaenmarchadedichasnecesidades.

25

Parte2.IntroduccinaGrails

Parte2

IntroduccinaGrails

Todotieneuninicio.Todosurgeporunarazn.Cuandounnuevo paradigma llega a romper las reglas establecidas, viene con ideas novedosas que generalmente mejoran y facilitan las prcticas actuales.Grailsnoeslaexcepcin.Grailshallegadopararomperel paradigma de que el desarrollo de aplicaciones web en Java es un procesocomplicado. AtravsdelCaptulo3:Porqu Grails?,sedaunaintroduccina los frameworks de Java utilizados desde el surgimiento de la plataforma Enterprise de dicho lenguaje. Se exploran las caractersticasprincipalesdecadaunodeellosyalfinal,seexplica con detalle qu es Grails, sus atributos, aplicaciones, ventajas y desventajas. En el Captulo 4: Creacin y arranque del sistema, se inicia la creacin de la aplicacin web para la administracin de PROMEP UAEH.Eldesarrollodedichaaplicacintienecomometasmostrarlas capacidades de Grails y motivar al lector en el aprendizaje de las mismas.

26

Captulo3.PorquGrails?

Captulo3

PorquGrails?

Para entender y apreciar el origen, funcionamiento y poder de Grails, es necesario conocer un poco de historia acerca de las tecnologas de desarrollo de aplicaciones Web en las cuales est basado. Las siguientes secciones guan al lector a travs de las principalesherramientasutilizadasendichodesarrollo.

3.1

Eliniciodetodo:EllenguajedeprogramacinJava

Java surgi en el ao 1995 en una presentacin de Sun MicrosystemsenSandHillRoad,MenloPark,California.Sucreador, JamesGosling [JGO01],concibi laideadegenerarunlenguajede programacinquefueracompletamenteorientadoaobjetos,portable entre diversas plataformas y que pudiera ejecutarse en diversos dispositivoselectrnicos,principalmentemviles. LasintaxisdeJavaseasemejamuchoaladeCyC++,lenguajesen los que est escrito. Java posee caractersticas que lo hacen nico [DEI07]: No utiliza apuntadores, liberando al usuario de la administracindirectadelamemoria. Java es compilado en bytecodes en archivos con extensin .class. Dichos archivos son interpretados por un programa denominadoMquinaVirtualdeJava(JVM,porsussiglasen ingls). sta JVM est escrita de forma nativa para cada sistema operativo, lo que hace portables a las aplicaciones

27

Captulo3.PorquGrails?

escritasenJava: WriteOnce,RunEverywhere esunodelos lemasdeSunMicrosystemsparadicholenguaje. Javanopermitela sobrecargadeoperadores talcomolohace C++. Java no usa herencia mltiple como tal, sino que posee un mecanismodeimplementacindevariasclasesconocidascomo interfaces. Seutilizaunmecanismoautomticodeliberacindememoria conocidocomo garbagecollector,elcualdetectareferenciasno utilizadasonulasyliberasusrecursos.Conestemecanismo,el programadorevitaproblemasdefugasdememoria. El rendimiento de una aplicacin de Java es competente con unaaplicacinescritaenC++.SehademostradoqueJavaes 1.1vecesmslentoqueC++1,yenmuchoscasos,esmsrpido queC++[TSS04]. Javasedivideen3partesdeacuerdoalentornodeejecuci n:Java StandardEdition(JSE),cuyodesarrolloseenfocaaaplicacionesde escritorio; Java Enterprise Edition (JEE), cuyo objetivo es hacia aplicaciones empresariales que manejan bases de datos, servicios web, mensajera asncrona, correo electrnico, entre otras funcionalidades; y Java Micro Edition (JME), cuyas aplicaciones se ejecutan en dispositivos mviles como son celulares, PDA's,
1 La version 1.0 de Java era de 20 a 40 veces ms lenta que C++ [KGP05]. A partir de la versin 1.5, el rendimiento se logr optimizar hasta 1.1 veces. Al momento de escribir este documento, la version de Java es la 1.6.0.24.

28

Captulo3.PorquGrails?

Blackberries,Smartphones,entreotros. Grails utiliza JEE para gran parte del desarrollo de aplicaciones web,as comoJSEparalacreacindemdulosquesecomunican conotrasaplicaciones.

3.2

JavaEnterpriseEdition

Java Enterprise Edition (JEE) es una plataforma ampliamente utilizadaparalaprogramacindeaplicacionesdeservidorescritasen Java.DichaplataformadifieredelaversinJSEenquelaprimera aade bibliotecas de clases que proporcionan funcionalidad para aplicacionesmulticapa,distribuidasytolerantesafallas. Las aplicaciones para JEE se ejecutan en un servidor de aplicaciones,elcualesunprogramaescritoenJavaquepermiteel despliegue de pginas web, conexiones a bases de datos, administracin de sesiones, entre otras cosas. Los archivos de la aplicacin JEE se colocan en una ubicacin propia del servidor de aplicaciones y ste se encarga de desplegarla. Los servidores de aplicacionesmspopularesson: ApacheTomcat[APT01]. GlassFish[GLA01]. Websphere[WEB01]. Jetty[JET01]. Weblogic[WLO01].

29

Captulo3.PorquGrails?

AlgunasdelasbibliotecasdeclasesdeJEEson: JDBC(JavaDatabaseConnectivity)paratratamientodebases dedatos[JDB01]. RMI(RemoteMethodInvocation)paraelusodeprocedimientos remotos[RMI01]. JavaMailparacorreoelectrnico[JMA01]. JMS(JavaMessageService)paraelusodecolasdemensajes [JMS01]. JAXWS (Java API for XML Web Services) para la implementacindeserviciosWeb[JAX01]. JSP (JavaServer Pages) para la creacin de pginas web dinmicas[JSP01]. Se recomienda consultar [JEE10] para un tratamiento ms profundodeJavaEnterpriseEdition.

3.3

Latecnologabase:Servlets

El desarrollo de aplicaciones web con JEE se basa en la programacindeclasesqueseencargandegestionarlaspeticiones HTTPhechasalservidor.DichasclasessondenominadasServlets.Los servletssonunatecnologamodernacapazdeadministrarsolicitudes yrespuestasmedianteelprotocoloHTTP.Losservletssonpuestosen marcha mediante servidores de aplicaciones y archivos de configuracinqueindicanlosservletsautilizarparalagestindela aplicacinweb.

30

Captulo3.PorquGrails?

ComolosservletssonclasesdeJava,tienenlafacultaddeprocesar cualquiertipodelgicadenegociosycompartirlaentradaysalidade dichalgicaconunsitioweb.EstacaractersticaeslaesenciadeJava EnterpriseEdition:recibirdatosdeentradamedianteHTTP,procesar dichosdatosmediantelalgicadenegociosimplementadaconJavay enviar una respuesta generada por dicha lgica nuevamente por mediodeHTTP. Unservletescritodeformamanualpuedeserunatareadif cil.Los frameworks para aplicaciones webfacilitan dicha tarea abstrayendo granpartedelafuncionalidaddestatecnologa.

3.4

Frameworks:encapsuladoyabstraccinde funcionalidad

ConlallegadadeJEE,losservletsylosservidoresdeaplicaciones, eldesarrollowebconJavacomenz adifundirseentrelacomunidad de desarrolladores. Con el paso del tiempo, stos comenzaron a percatarsedequelacodificacindeaplicacioneswebinvolucrabala repeticinpasivademuchospasos,especialmenteenlaconfiguracin inicial. Asimismo, la experiencia adquirida proporcion a los programadores una serie de patrones de diseo que podan implementarseconelfindemejoraryacelerarlaimplementacinde software. Aunado a esto, la velocidad de desarrollo de aplicaciones web comenz a incrementarse cuando la Internet fue explotada no solo con fines informativos, sino con fines lucrativos, comerciales, acadmicos,sociales,etc. Teniendo en cuenta que la velocidad de desarrollo poda

31

Captulo3.PorquGrails?

incrementarse mediante la automatizacin de ciertos procesos y la aplicacindepatronesdediseo,comenzaronasurgirlosframeworks de aplicaciones. Un framework es un conjunto de herramientas diseadoparaacelerar,mejorarysimplificareldesarrollodesoftware. Puedenserdepropsitogeneralopropiosdeun rea.Losframewoks de propsito general son la solucin a la creacin de la estructura general de programas, mientras que los frameworks propios de un reaseenfocanenunoovariosmdulos. DesdeelsurgimientodeJava,elnmerodeframeworkshacrecido de forma desmesurada. Dos de ellos han adquirido bastante popularidaddebidoasuestabilidad,robustezyfacilidaddeusoenel desarrollo de aplicaciones web: Spring, que es un framework de propsito general para el desarrollo de aplicaciones web y de escritorio2,yHibernate,unframeworkdiseadoparamanejarbases dedatosconelparadigmadeProgramaci nOrientadoaObjetos.Las siguientesseccionesexplicandichasherramientas.

3.5

FacilitandoJEE:SpringFramework

EldesarrollodeaplicacioneswebconJEEcontenadetallesquelo hacanlentoyrepetitivo.Teniendoestoencuenta,RodJohnson,un desarrolladorfrreodeJEEdesde1996,public ensu libro Expert OneonOne J2EE Design and Development [SPR02] una serie de herramientasquefacilitaban,acelerabanysimplificabaneldesarrollo deaplicacioneswebenJEE.Esteconjuntodeherramientasfueronla
2 Al momento de escribir este documento, Spring Source estaba desarrollando Spring Mobile, un mdulo para la creacin de aplicaciones dirigidas hacia dispositivos mviles.

32

Captulo3.PorquGrails?

basedeloquemsadelanteseraSpringFramework. Spring es un conjunto de herramientas que promueven la separacindelosmdulosdeunaaplicacinmediantelaInyeccinde Dependencias[DIN04],unconceptorelativamentenuevoquepropone el bajo acoplamiento entre componentes, asi como su reutilizacin dentro del mismo programa. Por otra parte, Spring Framework abstrae mucha de la funcionalidad de JEE mediante la automatizacindestaoproporcionandoversionesmssencillas. En los ltimos aos, Spring ha ganado popularidad entre los desarrolladoresdesoftwareyescadavezmsutilizadoenlacreacin deaplicacionesweb.Asimismo,Springnosehalimitadoaldesarrollo WebenJava,sinoquehaimplementadovariosproyectosrelacionados conotrasherramientas,lenguajesyentornos.Ejemplosdestoson: SpringBlazeDSIntegrationparaeldesarrolloconAdobeFlex [FLX01]. SpringPython[PYT01]. Spring.NET[SDN01]. SpringMobileparadispositivosmviles[SMO02].

Paraunamejorreferencia,sepuedeconsultar[SPR01].

3.6

PersistenciaOrientadaaObjetos:HibernateFramework

EnJEE,elusodeconexionesabasesdedatosesunatareamuy comn.EstoselograutilizandoelAPIJDBC.Sufuncionalidadb sica consisteenrealizarunaconexinmedianteuncontrolador(driver)y

33

Captulo3.PorquGrails?

por medio del mismo hacer peticiones al gestor de base de datos mediante SQL (Structured Query Language). Una vez hechas las peticiones,setraducenyseprocesanlosresultadosmedianteJava. ExistenvariosinconvenientesalutilizarJDBC.Enprimerlugar,la granvariedaddegestoresdebasesdedatosprovocaquecadaunode ellos contenga versiones diferentes de SQL, lo cual aminora la portabilidad de una aplicacin y dificulta su mantenimiento. Asimismo, la extraccin de los datos obtenidos mediante las peticionesesunprocesoredundanteydependientedeltipodegestor utilizado. Por ejemplo, mientras que MySQL [MSQ01] representa nmerosenterosmediante integer,SQLServer [MSS01] lohacecon numeric. Hibernate es un framework enfocado al uso de bases de datos desarrolladoporJBossqueeliminalosproblemasantesmencionados. UtilizaelparadigmaObjectRelationalMapping (ORM,porsussiglas eningls),elcuallepermiteaunprogramamanipularunabasede datos relacional con el paradigma de la programacin orientada a objetos. Con ello, a nivel de la aplicacin, las tablas se vuelven objetos,losregistrosseconviertenenatributosdelobjeto,lasllaves forneassetransformanenasociacionesentreobjetosylasconsultas setraducenenllamadasamtodos. Hibernate libera al desarrollador de la escritura del 95% de sentencias SQL, lo que aumenta la velocidad de desarrollo y portabilidadentregestoresde basesde datos.Asimismo, Hibernate proporciona su propio lenguaje de consultas denominado HQL

34

Captulo3.PorquGrails?

(HibernateQueryLanguage),elcualesmuyparecidoaSQLperocon ladiferenciadequeescompletamenteorientadoaobjetos. ElsitiooficialdeHibernate[HIB01]esunaexcelentereferenciapara untratamientoadetalledeesteframework.

3.7

Laevolucinnatural:Lenguajedeprogramacin Groovy

Javahamostradoserunlenguajedeprogramaci npoderosoyde alto nivel. Sin embargo, posee caractersticas que en algunas ocasiones vuelve redundante la codificacin. Algunos lenguajes orientados a objetos, como Python, SmallTalk y Ruby, poseen caractersticas dinmicas que Java no tiene, lo que ocasiona que muchosdesarrolladoresoptenporcambiardelenguaje. Groovy surgi en el ao 2003 gracias a la iniciativa de James StrachanyBobMcWhirter.Laintencindedicholenguajenoesser elsucesordeJava,yaquetodalafuncionalidadde steseencuentra disponible en Groovy. Asimismo, Groovy no est escrito sobre Java (asicomoJavaest escritoenCyC++),sinoqueesotrolenguajede programacinparalaJVM,loquelohacecompletamentecompatible conaplicacionesJavaexistentesyviceversa. GroovyposeecaractersticasdeJava,Ruby,PythonySmallTalken unslolenguaje,loqueloconvierteenunlenguajepoderosoyfcilde usar.LacurvadeaprendizajedeGroovyparalosdesarrolladoresde Javaesrelativamentepequea,locuallespermitecrearaplicaciones enGroovydeformainmediata.LosdesarrolladoresdeGrailseligieron

35

Captulo3.PorquGrails?

aGroovycomosulenguajebasedebidoasupoderydinamismo. SerecomiendaconsultarlapginaoficialdeGroovy [GRO01] para untratamientomsprofundoacercadeestelenguaje.

3.8

Descubriendoelgrial:Grails

El uso compartido de Spring y Hibernate es muy comn en aplicaciones de JEE, ya que esto acelera y facilita el desarrollo de aplicacionesweb.AmbosframeworksutilizanXMLparasusm dulos de configuracin3. Para algunos desarrolladores, utilizar esta nomenclatura puedeser una tarea complicada, yaque involucra la repeticindecdigocuyoobjetivopodralograrsedeunaformams simple. Comoyasemencion conanterioridad,Hibernateutilizallamadas a mtodos para la realizacin de consultas. En la gran mayora de aplicaciones,seutilizan4mtodosquecoincidenconlasoperaciones CRUD de una base de datos: Create (crear), Read (leer), Update (actualizar) y Delete (eliminar). La codificacin de estos mtodos se vuelvemuyrepetitiva,locualabrelapautaparasuautomatizacin. Grailssurgeenelao2006comounarespuestaalanecesidadde agilizar,automatizarysimplificareldesarrollodeaplicacionesWeb. GrailsestbasadoenSpring,HibernateyGroovy,ytomalasmejores prcticas de cada uno de ellos para formar un marco de trabajo estable,robusto,sencillodeusarydefcilmantenimiento. El libro Grails in Action [GRA09] maneja 7 Grandes Ideas que
3 En versiones recientes de Spring y Hibernate, se promueve el uso de anotaciones en lugar de XML.

36

Captulo3.PorquGrails?

hacen nico a Grails sobre otras herramientas. Las siguientes seccionesexplicanestospuntos. 3.8.1 ConvencinsobreConfiguracin Grailsposeeunaestructuraespecialparalaubicacindecadauno desuselementos,clasesyarchivosdeconfiguracin: Lasclasesdedominioseencuentranununacarpetallamada domain. Loscontroladoresestnenlacarpetacontrollers. Laspginaswebselocalizanenlacarpetaviews. Losarchivosdeconfiguracinseubicanenlacarpetaconf.

Elnombredeloscontroladores,vistasyURL'sgeneradasporGrails dependen del nombre de la clase de dominio correspondiente. Por ejemplo, si se tiene una clase llamada Profesor, el controlador se nombra ProfesorController y las vistas se ubican en views/profesor, Asimismo,lasURL'sparaaccederalasvistassebasanenelnombre de stas.Ejemplodeelloeslavista list,cuyavistaseencuentraen views/profesor/list.gsp y su correspondiente URL sera http://nombre_aplicacion/profesor/list. Como puede observarse se siguen ciertasconvencionessobre las clasesdedominio,controladores,vistasyURL's.Dichasconvenciones ahorran al desarrollador la tarea de configurar la correspondencia entreestosmdulosmedianteXML.AestacaractersticadeGrailsse leconocecomoConvencinsobreConfiguracin.

37

Captulo3.PorquGrails?

3.8.2 Filosofagil LaprincipalraznporloqueGrailsviolaluzfuelanecesidadde desarrollaraplicacionesrpidamente.AtravsdelaConvencinsobre Configuracin,seaceleraelprocesoinicialdecodificacin.Porotra parte,Grailspermitehacercambiosyvisualizarlosentiemporealsin necesidaddereiniciarelservidordeaplicaciones(accinmuycomn con otras herramientas). Una aplicacin Grails puede generarse y ejecutarseconsolo2comandos,yencuestindeminutos,sepueden desarrollarfuncionalidadessorprendentes. 3.8.3 Fundamentosslidos Grails esta implementado sobre las mejores herramientas de desarrollo existentes para lograr sus objetivos. Como ya se ha mencionado con anterioridad, Grails est fuertemente basado en Spring, Hibernate y Groovy, tecnologas ampliamente aceptadas y reconocidasporsuestabilidadymadurez.Porlotanto,Grailstiene unsoporteslidoquelorespaldacomounaexcelenteherramientade desarrolloweb. 3.8.4 PlantillasyScaffolding Paralageneracinautomticadecdigo,Grailsmanejaelconcepto de scaffolding. Basado en la estructura de las clases de dominio, sta tcnica genera deformadinmica elcdigonecesarioparalos controladoresyvistassinnecesidaddeescribircdigoparaelloysin necesidad de la existencia de sus archivos correspondientes. Grails utiliza una serie de plantillas para la generacin de ste cdigo,

38

Captulo3.PorquGrails?

creandocontroladoresyvistasconsistentesyentiemporeal. Naturalmente, no todas las aplicaciones web requieren la funcionalidad que las plantillas ofrecen. Grails ofrece la opci n de modificarlas de acuerdo a las necesidades del desarrollador, permitindoleagregarmayorfuncionalidad.Unavezquelasplantillas son modificadas, los artefactos correspondientes (controladores y vistas) pueden ser generados con las necesidades especficas de la aplicacin ya incluidas. Esto tiene aplicacin en pginas web que necesitanconsistenciayuniformidadtantoensusfuncionescomoen suapariencia. 3.8.5 IntegracinconJava ProbablementesetenganmdulosdesarrolladosenJavayexistala necesidad de integrarlos con Grails. Groovy es completamente compatible con Java y viceversa, lo cual permite utilizar cualquier clase, API y biblioteca de clases de Java en Grails 4. Todo el conocimiento adquirido con Java puede ser aplicado con Groovy y Grails. Asimismo, Grails permite crear clases en Java desde cero comosifueraunaaplicacin100%hechaendicholenguajeComose dijoantes,Groovynopretendeserlacompetencianimuchomenosel sucesordeJava. 3.8.6 Wetware Alolargodecasi5aos,Grailshaganadomuchosseguidores,lo
4 Para que las clases Groovy puedan ser utilizadas en una clase Java, se requiere agregar un archivo JAR en el CLASSPATH de la aplicacin. Dicho JAR contiene la infraestructura bsica de Groovy.

39

Captulo3.PorquGrails?

quehaincrementadoelnmeroderecursosdedicadosalsoportey mantenimientode staherramienta.SitiosWeb,forosdediscusin, libros,podcastsysobretodoeldesarrolloexponencialdepluginsson algunosdelasherramientasdisponiblesparanovatosyexpertosenel desarrollodeaplicacioneswebconGrails.Elrecursomsimportante es el sitio web oficial [GRA01], donde el lector puede encontrar el software, la documentacin, foros, enlaces a otros sitios, plugins, entreotrascosas. 3.8.7 Productividad Sin duda, una de las consecuencias ms evidentes del uso de Grailseselniveldeproductividadqueseobtiene.Unaaplicacinque podra llevar semanas o incluso meses queda lista en cuestin de horasodasconGrails.Estopermitealosdesarrolladoresenfocarse enotrosaspectoscomosonlalgicayreglasdenegocio,esttica,la presentacin,documentacin,capacitacin,etc.

3.9

Resumen

GrailsesunaherramientapoderosabasadaenellenguajeGroovy queagilizaysimplificaeldesarrollodeaplicacioneswebenJEE.El hechodequeestbasadasobreframeworksmadurosyestablescomo sonSpringyHibernatelohacesumamenteconfiableyfcildeusar. Sudinamismoeintuicinloconviertenenunaexcelenteopcinpara lafilosofagildecreacindeprogramas.

40

Captulo4.Creacinyarranquedelsistema

Captulo4

Creacinyarranquedelsistema

En este captulo se inicia la codificacin del sistema CSI de PROMEPUAEH.Graciasalafacilidaddeimplementacinqueofrece Grails,esposibleponerenmarchaelsistemadeformainmediata.En captulos posteriores, conforme se desarrollan los tpicos concernientesaGrails,cadaunoesejemplificadoconunm dulodel sistema.

4.1

Generacindelaaplicacin

SiannosetieneinstaladoGrails,sesugiereconsultarelAnexoA: Instalacin de Grails, el cual contiene las instrucciones necesarias parasuinstalacinendiversossistemasoperativos. Para generar una aplicacin con Grails, se escribe el siguiente comando:
>grailscreateapp{nombredelaaplicacin}

ParaelcasodelsistemaCSI,elcomandoseejecutadelasiguiente forma:
>grailscreateappBDPromep

Estovaagenerarundirectoriollamado BDPromep,ydentrodeste se encuentran todas los archivos y directorios necesarios para la aplicacin.Laestructuradedirectoriosobtenidaeslasiguiente:

41

Captulo4.Creacinyarranquedelsistema
BDPromep/ |grailsapp ||conf ||controllers ||domain ||i18n ||services ||taglib ||utils |`views |lib |scripts |src |test `webapp

grailsapp/conf: contiene los archivos de configuracin de basesdedatos,propiedades, URL's,accionesaejecutarenel arranquedelaaplicacin,entreotros.

grailsapp/controllers: aqu se colocan los archivos fuente correspondientesaloscontroladoresdelaaplicacin.

grailsapp/domain:enestacarpetaseencuentranlasclasesde dominio.

grailsapp/i18n: aqu estn los archivos de mensajes de internacionalizacindelaaplicacinquelepermitenadaptarel idiomadeacuerdoallenguajedelnavegador.

grailsapp/services: las clases que modelan los servicios

42

Captulo4.Creacinyarranquedelsistema

generadosporGrailssecolocanenestedirectorio. grailsapp/taglib: las clases que modelan los taglibs para GroovyServerPages(GSP)sealojanenestacarpeta. grailsapp/utils: aqu se colocan las clases utilitarias especficasdeGrails5. grailsapp/views: los archivos para las pginas web GSP se encuentranaqu. lib: en esta carpeta se colocan los archivos JAR que la aplicacinrequierayqueGrailsnoincluyapordefecto. scripts:aqu secolocanlasclasescreadasporeldesarrollador quepuedenejecutarsecomoscripts. src: siesnecesariogenerarcdigoJavaoGroovyademsdel generadoporGrails,sedebecolocarenstedirectorio. test: laspruebasunitariasydeintegracinseponenenesta carpeta. webapp: aqu se ubican todos los archivos de configuracin, JavaScript, imgenes y recursos estticos propios de la aplicacinweb. Paralapuestaenmarchadelaaplicacin,seescribeelsiguiente comando:
5 En muchas aplicaciones de Java se manejan clases utilitarias, las cuales funcionan como clases auxiliares que proporcionan funcionalidad propia de la aplicacin que se utiliza en varios mdulos de la misma. El directorio grails-app/utils de Grails se utiliza para colocar cdecs especificos de la infraestructura de Grails, no de la aplicacin desarrollada en s. Por esta razn, rara vez es utilizado.

43

Captulo4.Creacinyarranquedelsistema
>grailsrunapp

Si todo marcha bien, al final de su ejecucin, Grails muestra la siguientesalida:


Serverrunning.Browsetohttp://localhost:8080/BDPromep

Para visualizar la aplicacin, se debe abrir un navegador web y dirigirse a la direccin http://localhost:8080/BDPromep. El navegador muestralapginadelaFigura6.

Figura 6: Pgina inicial de la aplicacin.

ElpanelizquierdodelapginadelaFigura6despliegainformacin acerca de las versiones de la JVM (Java Virtual Machine), de la aplicacin, de losdiferentes plugins instalados, deGroovy y Grails, entreotrosdatos.

44

Captulo4.Creacinyarranquedelsistema

Grails ha generado y desplegado de forma automtica toda la infraestructuranecesariaparaunaaplicacinweb.Nohaynecesidad deinstalarunservidordeaplicaciones,nohaynecesidaddeescribir archivos XML como ocurrira con cualquier otro framework de desarrollowebynohaynecesidaddeescribirHTMLparalapgina inicial.Grailsautomatizatodosesospasos.

4.2

Lgicadenegocios:creacindelasclasesdedominio

Lageneracindelasclasesdedominiodeunaaplicaci nweben Grailsseencargadecodificarlasentidadesobtenidasenlafasede anlisis y diseo. Dicha codificacin se realiza mediante archivos .groovy. Para la creacin de una clase de dominio, se utiliza el comandograilscreatedomainclass:
grailscreatedomainclass{paquetedelaclase}{Nombredelaclase}

Para ejemplificar el uso de este comando, se genera la clase Profesorenelpaquetemx.edu.uaeh.promep:


grailscreatedomainclassmx.edu.uaeh.promep.Profesor

Sinoseescribepaquetealguno,Grailsgeneraunpaqueteconel nombre de la aplicacin web6, lo cual, en este caso, sera bdpromep.Profesor. Nteselaconversinaminsculasdelnombrede la aplicacin. Esto con el fin de cumplir con las convenciones de nombramientodepaquetesenJava. Laejecucindelcomandogenera2archivos: BDPromep/grails

6 En versiones anteriores de Grails no se generaba un paquete por defecto.

45

Captulo4.Creacinyarranquedelsistema

app/domain/mx/edu/uaeh/promep/Profesor.groovy,elcual correspondealaclasededominio. BDPromep/grails app/test/unit/mx/edu/uaeh/promep/ProfesorTests.groovy, enelcualserealizanlaspruebasunitariasdelaclaseProfesor. Alabrirelarchivo Profesor.groovy enuneditordetexto,sepuede observarelsiguientecontenido:


1.packagemx.edu.uaeh.promep 2. 3.classProfesor{ 4. 5.staticconstraints={ 6.} 7.}

Existe un paquete, el nombre de la clase y un closure donde se especifican las restricciones de los atributos de la clase. Las restricciones indican los lmites de cada atributo, tales como su tamao, su obligatoriedad, si deben seguir un patrn, entre otros. EstetemaseestudiaadetalleenelCaptulo5. ParamodelarlaclasedeacuerdoaldiagramadeclasesdelAnexo B,semodificalaclasecomosemuestraacontinuacin:
1.packagemx.edu.uaeh.promep 2. 3.classProfesor{ 4. 5.Stringfolio 6.Stringpaterno

46

Captulo4.Creacinyarranquedelsistema
7.Stringmaterno 8.Stringnombre 9.Stringcurp 10.Charactersexo 11.Stringemail 12.StringtelefonoTrabajo 13.StringtelefonoCasa 14.Booleanplantilla 15.IntegeranioPlantilla 16. 17.staticconstraints={ 18.folionullable:true,maxSize:15 19.paternonullable:true,maxSize:60 20.maternonullable:true,maxSize:60 21.nombrenullable:true,maxSize:60 22.curpnullable:true,maxSize:20 23.sexonullable:true,maxSize:1 24.emailnullable:true,maxSize:100 25.telefonoTrabajonullable:true,maxSize:50 26.telefonoCasanullable:true,maxSize:50 27.anioPlantillanullable:true 28.} 29.}

Se han agregado los atributos y sus restricciones. Gracias a la naturaleza dinmica de Groovy, no hay necesidad de colocar los clsicosmtodossettersygettersparaelaccesoymanipulacindelos atributosdelaclase.

4.3

Interaccinconelmundoexterior:controladoresy vistas

En la prctica, Grails utiliza el patrn de diseo MVC (Modelo

47

Captulo4.Creacinyarranquedelsistema

VistaControlador) [MVC01],elcualconsisteensepararlalgicade negocios de las interfaces grficas de usuario y lograr una comunicacin(nounamezcla)entreellaspormediodecontroladores. Laclasededominiocreadaenlaseccin4.2 correspondealalgica denegocios.ParalacreacindecontroladoresyvistasenGrailsse utilizanlossiguientescomandos: createcontroller:Generaunaclasecontroladorasincdigo.Se utilizaparalacreacindecontroladorescuyocdigoesescrito deformamanual. generatecontroller:Generaunaclasecontroladoracontodoel cdigonecesariopara administrarlaspeticioneshechasporel clienteweb.EstoseexplicaadetalleenelCaptulo7. generateviews: Crea todoslos archivos GSPnecesariospara lasvistas. generateall: Generatantocontroladorescomovistas,equivale aejecutarloscomandosgeneratecontrollerygenerateviewsen unsolopaso. Estoscomandosrecibencomoargumentolaclasededominioala cualselegenerarnlosartefactos.Amaneradeejemplo,lacreacin del controlador para la clase Profesor se realiza de la siguiente manera:
grailscreatecontrollermx.edu.uaeh.promep.Profesor

Puede observarse que se debe especificar la ruta completa de la clase,incluyendolospaquetes.Elcontroladorgeneradoesnombrado

48

Captulo4.Creacinyarranquedelsistema

ProfesorController,ysucontenidoeselsiguiente:
1.packagemx.edu.uaeh.promep 2. 3.classProfesorController{ 4. 5.defindex={} 6.}

Enlaseccin3.8.4sehabl acercadelatcnicadescaffolding,la cualgenera deformadinmica elcdigodeloscontroladoresylas vistas sin necesidad de que exista. Para lograr dicha propiedad, se modificaelcontroladordelasiguientemanera:
1.packagemx.edu.uaeh.promep 2. 3.classProfesorController{ 4.staticscaffold=true 5.}

En la ventana del navegador mostrada en la Figura 6, se debe actualizar la pantalla (generalmente con la tecla F5) y se debe visualizarunvnculoalcontroladorjustodebajodelttulo Available Controllers,talcomolomuestralaFigura7.

Figura 7: Pgina inicial de la aplicacin con un vnculo al controlador.

49

Captulo4.Creacinyarranquedelsistema

Alhacerclicenelvnculo,laaplicacinsedirigehacialapantalla principaldelcatlogodeProfesores,comosemuestraenlaFigura8.

Figura 8: Pantalla principal del catlogo de Profesores.

Alaccederalvnculo NewProfesor,Grailsmuestraunformulario semejantealdelaFigura9.

Figura 9: Pgina de creacin de registros.

50

Captulo4.Creacinyarranquedelsistema

Alintroducirdatosenelformularioderegistros,laaplicaci ndirige alusuarioalapantallamostradaenlaFigura10.

Figura 10: Confirmacin de la creacin del registro.

La aplicacin muestra una notificacin de que el registro fue insertado exitosamente. Asimismo, puede observarse que se despliegancadaunodeloscamposinsertados7.GrailsgeneraunID numricoautoincrementalparacadaclasededominio.Lasopciones deedicinyborradodelregistroaparecenenlaparteinferior. Todas las pginas web y las acciones de creacin, visualizacin, actualizacin y borrado de registros se generan con la creacin del controladorysuvariableesttica scaffold.Comopuedeobservarse, GrailsautomatizaeldesarrollodecatlogosCRUD.Naturalmente,se pueden obtener los archivos correspondientes a los controladores y
7 En la imagen, se omiten los datos introducidos por confidencialidad de datos.

51

Captulo4.Creacinyarranquedelsistema

lasvistasmedianteloscomandosgeneratecontroller,generateviewsy generateall,loscualessoncompletamenteeditablesdeacuerdoalas necesidadesdelaaplicacin.Paragenerartodoenunsolopaso,se sugiereejecutarlasiguientesentencia:


grailsgenerateallmx.edu.uaeh.promep.Profesor

Al momentode la ejecucin, Grails encuentra que el controlador para la clase Profesor ya existe y pregunta al usuario si se debe sobrescribirdichoarchivo:
File.../ProfesorController.groovyalreadyexists.Overwrite?[y,n,a] TestsProfesorControllerTests.groovyalreadyexists.Overwrite?[y/n](y,Y, n,N)

Cabe mencionar que existe un tiempo lmite para escribir la respuestaadichocomando.Laestructuradelosarchivosgenerados (sinincluirlosarchivosdepruebas)eslasiguiente:
BDPromep/ |grailsapp |controllers |`mx/edu/uaeh/promep |`ProfesorController.groovy `views `profesor |create.gsp |edit.gsp |list.gsp `show.gsp

El principio Convencin sobre Configuracin mencionado en la seccin 3.8.1 se hace presente. Los nombres de los directorios y

52

Captulo4.Creacinyarranquedelsistema

archivos de las vistas corresponden con las URL's enviadas al servidor.Asimismo,comosedescribeenel Captulo7,losnombres tambincorrespondenconlasaccionesdelcontrolador.

4.4

Persistencia:almacenamientodedatosenGrails

GrailspermitelacreacindecatlogosCRUDdeformarpida.Por defecto, Grails utiliza la tecnologa HSQLDB [HSQ01] para generar una base de datos in memory (en memoria), lo que significa que mientraselservidordeaplicacionesnoseapagueoreinicie,losdatos almacenados en memoria se conservan. El uso de esta tecnolog a pemitealdesarrolladorhacerpruebasdesuaplicacinsinnecesidad derealizarlaconexinconunabasededatosreal. Grailsutiliza3entornos:desarrollo(development),pruebas(test)y produccin (production). La ejecucin, empaquetado de WAR (el archivoentregable),conexinabasededatos,entreotrasacciones, pueden ser configuradas para cada uno de estos entornos. Por defecto,Grailstieneestablecidoelentornodedesarrollo. Echandounvistazoalarchivodeconfiguracin BDPromep/grails app/conf/DataSource.groovy,setienelosiguiente:
1.dataSource{ 2.pooled=true 3.driverClassName="org.hsqldb.jdbcDriver" 4.username="sa" 5.password="" 6.} 7.hibernate{ 8.cache.use_second_level_cache=true

53

Captulo4.Creacinyarranquedelsistema
9.cache.use_query_cache=true 10.cache.provider_class='net.sf.ehcache.hibernate.EhCacheProvider' 11.} 12.//environmentspecificsettings 13.environments{ 14.development{ 15.dataSource{ 16.dbCreate="createdrop"//oneof... 17.url="jdbc:hsqldb:mem:devDB" 18.} 19.} 20.test{ 21.dataSource{ 22.dbCreate="update" 23.url="jdbc:hsqldb:mem:testDb" 24.} 25.} 26.production{ 27.dataSource{ 28.dbCreate="update" 29.url="jdbc:hsqldb:file:prodDb;shutdown=true" 30.} 31.} 32.}

En JDBC, se requieren 4 parmetros bsicos para la conexin a unabasededatos: Driver: eselnombredeunaclasecontroladoraquepermitela conexinaungestordebasesdedatos.Cadafabricanteprovee unJARquedebeseragregadoal CLASSPATHdeunaaplicacin Javayquecontienedichaclase. Url:contienelaubicacindelabasededatos.

54

Captulo4.Creacinyarranquedelsistema

Username:secolocaelnombredeusuario. Password:secolocalacontraseadelusuario. DSL (Domain Specific Language) del archivo

El primer

DataSource.groovy nombrado dataSource, contiene 3 de los 4 parmetros principales de conexin a una base de datos: driver, usernameypassword.ElsegundoDSLllamadohibernatecontienelas propiedadesquedeformamanualsetendranqueconfigurarenel archivohibernate.cfg.xml8.EltercerDSLcontienelostresentornosde Grailsantesmencionados.Encadaunodeellossepuedeconfigurar un DSL de tipo dataSource. Por defecto, en cada uno de ellos se incluyen2propiedades: dbCreate: se refiere al tratamiento de la base de datos al momentodeiniciaryapagarelservidordeaplicaciones.Esta propiedadpuedetener3valores: create,quegeneralabasede datos desde cero (si ya existe, la destruye); createdrop, que realizalomismoquecreateperoalapagarelservidordestruye labasededatos,yupdate,que nicamenterealizacambiossin alterarlabasededatosexistente(siestanoexiste,segenera desdecero).Porejemplo,siseagregaunatributoaunaclase, seagregauncampoalatablacorrespondiente. Url: comoyasehabamencionadoanteriormente,contienela ubicacindelabasededatos.

8 Se sugiere consultar la documentacin oficial de Hibernate para un tratamiento ms profundo de todas las propiedades disponibles. Dicha documentacin se encuentra en [HDC01]

55

Captulo4.Creacinyarranquedelsistema

ComounejemplodelaportabilidadlogradaporHibernateyGrails hacia diferentes gestores de bases de datos, se va a cambiar el almacenamientodedatosdeHSQLDB aMySQL.Para ello,sedebe instalarelJARquecontieneelcontroladordeMySQL.Estoselogra modificandoelarchivo grailsapp/conf/BuildConfig.groovy.Elarchivo originalcontienelosiguiente:
1.grails.project.class.dir="target/classes" 2.grails.project.test.class.dir="target/testclasses" 3.grails.project.test.reports.dir="target/testreports" 4.//grails.project.war.file="target/${appName}${appVersion}.war" 5.grails.project.dependency.resolution={ 6.//inheritGrails'defaultdependencies 7.inherits("global"){ 8.//uncommenttodisableehcache 9.//excludes'ehcache' 10.} 11.log"warn"//loglevelofIvyresolver,either'error',... 12.repositories{ 13.grailsPlugins() 14.grailsHome() 15.grailsCentral() 16. 17.//uncommentthebelowtoenableremote... 18.//frompublicMavenrepositories 19.//mavenLocal() 20.//mavenCentral() 21.//mavenRepo"http://snapshots.repository.codehaus.org" 22.//mavenRepo"http://repository.codehaus.org" 23.//mavenRepo"http://download.java.net/maven/2/" 24.//mavenRepo"http://repository.jboss.com/maven2/" 25.}

56

Captulo4.Creacinyarranquedelsistema
26.dependencies{ 27.//specifydependencieshereundereither'build',... 28.//runtime'mysql:mysqlconnectorjava:5.1.13' 29.} 30.}

Bsicamente,estearchivoseencargadegestionarlasdependencias detercerosquepuedenseragregadasporeldesarrolladordeacuerdo a sus necesidades. Se puede observar que el ltimo DSL llamado dependencies tiene una dependencia en tiempo de ejecucin correspondiente al JAR de MySQL. Se asume que el lector tiene instaladodichogestordebasesdedatosyquetieneconocimientos bsicos de su uso. Para obtener dicho JAR, se sugiere detener la aplicacin escribiendo Ctrl+c en la ventana de comandos donde se est ejecutandoelservidorTomcat.Laconsolamuestraelsiguiente mensaje:
Applicationcontextshuttingdown... Applicationcontextshutdown.

Posteriormente, se modifica el archivo BuildConfig.groovy para habilitar los repositorios de Maven y descargar el JAR de MySQL (lneas19a24y28):
19.mavenLocal() 20.mavenCentral() 21.mavenRepo"http://snapshots.repository.codehaus.org" 22.mavenRepo"http://repository.codehaus.org" 23.mavenRepo"http://download.java.net/maven/2/" 24.mavenRepo"http://repository.jboss.com/maven2/" ... 28.runtime'mysql:mysqlconnectorjava:5.1.13'

Como segundo paso, se debe modificar el archivo

57

Captulo4.Creacinyarranquedelsistema

DataSource.groovy para colocar los 4 parmetros necesarios para realizarlaconexin:


1.dataSource{ 2.pooled=true 3.driverClassName="com.mysql.jdbc.Driver" 4.username="usuario" 5.password="contrasenia" 6.} ... 12.//environmentspecificsettings 13.environments{ 14.development{ 15.dataSource{ 16.dbCreate="update"//oneof... 17.url="jdbc:mysql://localhost:3306/promep" 18.} 19.} 20.test{ 21.dataSource{ 22.dbCreate="update" 23.url="jdbc:mysql://localhost:3306/promep" 24.} 25.} 26.production{ 27.dataSource{ 28.dbCreate="update" 29.url="jdbc:mysql://localhost:3306/promep" 30.} 31.} 32.}

Finalmente,sedebecrearunabasededatosenMySQLllamada promep y se inicia la aplicacin con el comando grails runapp. La

58

Captulo4.Creacinyarranquedelsistema

consoladebemostrarladescargadelJARdeMySQLyposteriormente el arranque de la aplicacin. Si todo marcha bien, al consultar las tablasenlabasededatospromep seobtieneunresultadosimilaral siguiente:
mysql>showtables; ++ |Tables_in_promep| ++ |profesor| ++ 1rowinset(0.00sec)

mysql>descprofesor; +++++++ |Field|Type|Null|Key|Default|Extra| +++++++ |id|bigint(20)|NO|PRI|NULL|auto_increment| |version|bigint(20)|NO||NULL|| |anio_plantilla|int(11)|YES||NULL|| |curp|varchar(20)|YES||NULL|| |email|varchar(100)|YES||NULL|| |folio|varchar(15)|YES||NULL|| |materno|varchar(60)|YES||NULL|| |nombre|varchar(60)|YES||NULL|| |paterno|varchar(60)|YES||NULL|| |plantilla|bit(1)|NO||NULL|| |sexo|char(1)|YES||NULL|| |telefono_casa|varchar(50)|YES||NULL|| |telefono_trabajo|varchar(50)|YES||NULL|| +++++++ 13rowsinset(0.00sec)

Para cada clase de dominio, Hibernate y Grails han creado una

59

Captulo4.Creacinyarranquedelsistema

tabla.Cadaatributodelasclasessecorrespondeconuncampodela tabla.Lasrestriccionesestablecidasencadaatributosereflejanenel tamaoyobligatoriedaddecadacampo.Graciasalatransparenciade Hibernateenelmanejodediferentesgestoresdebasesdedatos,la aplicacin generada con Grails no tiene conocimiento del gestor utilizado, lo que aumenta su portabilidad y facilidad de mantenimiento.

4.5

Resumen

A lo largo de ste captulo se han demostrado las capacidades bsicas de Grails. Con escribir unos cuantos comandos y algunas lneas de cdigo, se ha implementado una aplicacin web completamentefuncional,defcilmantenimientoysencilladeusar. El desarrollo de aplicaciones web con Grails se convierte un una experiencia gil e interesante. En la siguiente parte de este documento,FundamentosBsicosdeGrails,sedescribenconmayor detallelostpicostratadosen stecaptulo,ademsdeincluirtemas quesientanlasbasesparaeldesarrollodeaplicacionesreales.

60

Parte3.FundamentosBsicosdeGrails

Parte3

FundamentosBsicosdeGrails

Talcomoseexplic enlaseccin 2.4,lasaplicacionesgeneradas porGrailsconsistende3capas:lacapadelgicadenegocios,lacapa de controladores y la capa de presentacin. En la Parte 3 de este documentosedetallancadaunadeestascapas. Enel Captulo5: Dominiodeunaaplicacinweb,semuestranlos fundamentos del modelado de entidades, tales como la selecci n adecuadadeltipodeatributos,mtodos setter y getter,validacinde datos, personalizacin del mapeo para la base de datos y las relaciones existentes entre entidades (uno a uno, uno a muchos y muchosamuchos). Una vez entendidos los fundamentos de las entidades, en el Captulo 6: Modelo ObjetoRelacional en Grails (GORM) , se explica a detalleeltratamientodeGrailsparalapersistenciadeobjetosenuna basededatos.Semuestranlosmtodoscomunesatodoslosobjetos ysehacehincapi enlautilizacindemtodosdinmicos,Criteriay HQLparalarealizacindeconsultas. Paralapartedeinteraccinconelusuariofinal,enel Captulo7: CapadepresentacinWeb:ControladoresyGroovyServerPages, se presenta al lector la forma en que Grails implementa el patr n de diseo ModeloVistaControlador (MVC) para lograr, a travs de controladores, la interaccin del dominio con la interfaz grfica de usuariorepresentadaporlaspginasweb.Dichaspginastrabajan bajo la tecnologa de Groovy Server Pages, la cual contiene

61

Parte3.FundamentosBsicosdeGrails

funcionalidades poderosas que van desde la emulaci n de instrucciones de condicin, ciclos e impresin de variables con formato hasta la implementacin de llamadas asncronas Ajax con diversasbibliotecasconJavaScript.

62

Captulo5.Dominiodeunaaplicacinweb

Captulo5

Dominiodeunaaplicacinweb

Toda aplicacin computacional posee una parte que modela aspectos del mundo real. Con este modelado se realizan diversas operacionesquedanvidaaunprograma.Enunaaplicaci nweb,la lgica de negocios desempea este papel. En Grails, las clases de dominioseencargandeunaparteimportantedelalgicadenegocios abstrayendolasentidadesquesirvencomobaseparalacreaci nde unabasededatos.Enestecaptulosetratanadetalledichasclases.

5.1

Creacindeunaclasededominio

Talcomosemuestraenlaseccin4.2,lageneracindeunaclase de dominio en Grails se logra mediante el comando createdomain class.Lasintaxisdeestecomandoeslasiguiente:


>grailscreatedomainclass{paquete}{clase}

EjemplosdesuejecucinsonloscomandosescritosenelCaptulo 4:
>grailscreatedomainclassmx.edu.uaeh.promep.Profesor

Losarchivosgeneradosson2:unorepresentalaclaseens yse coloca en la carpeta grailsapp/domain. El segundo archivo es una claseparalaescrituradepruebasunitarias,ubicadoen test/unit.El nombre utilizado para la clase de pruebas es {paquete} {nombreClase}Tests.groovy. Si no se especifica un paquete, Grails genera por omisin un paquete con el nombre del proyecto en minsculasparaambosarchivos(seccin4.2).

63

Captulo5.Dominiodeunaaplicacinweb

5.2

Adicindeatributos

El contenido de la clase de dominio por defecto es similar al siguiente:


1.package{paquete} 2. 3.class{NombreClase}{ 4. 5.staticconstraints={ 6.} 7.}

Unapartemedulardelasclasesdedominiosonlosatributos.Los atributosdeunaclaserepresentanaquellascaracter sticaspropiasde la entidad a modelar. Para ejemplificar el uso de atributos de una clase,seretomalaclaseProfesordelCaptulo4:
1.packagemx.edu.uaeh.promep 2. 3.classProfesor{ 4. 5.Stringfolio 6.Stringpaterno 7.Stringmaterno 8.Stringnombre 9.Stringcurp 10.Charactersexo 11.Stringemail 12.StringtelefonoTrabajo 13.StringtelefonoCasa 14.Booleanplantilla 15.IntegeranioPlantilla 16. 17.staticconstraints={

64

Captulo5.Dominiodeunaaplicacinweb
18.folionullable:true,maxSize:15 19.paternonullable:true,maxSize:60 20.maternonullable:true,maxSize:60 21.nombrenullable:true,maxSize:60 22.curpnullable:true,maxSize:20 23.sexonullable:true,maxSize:1 24.emailnullable:true,maxSize:100 25.telefonoTrabajonullable:true,maxSize:50 26.telefonoCasanullable:true,maxSize:50 27.anioPlantillanullable:true 28.} 29.}

Lascaractersticasdeunprofesormodeladasenestaclasesonsu nombre, apellidos, sexo, CURP, entre otros. Naturalmente, las profesorestienenmscaractersticasquelasmencionadas,peropara el modelado de la aplicacin, stos atributos satisfacen los requerimientosdelamisma. Cadaunodelosatributossecaracterizaporun tipodedato.Los tiposdedatosindicanlanaturalezadelatributo.Enelmundoreal, existen datos numricos, alfabticos, lgicos, cronolgicos, etc. A continuacin, se hace un anlisis detallado de los tipos de datos soportadosporGrails. 5.2.1 Tiposdeatributos

Alhacerelmodeladodeatributosdeunaclase,esprecisoutilizarel tipodedatosquemejorseadaptealasnecesidadesdelaaplicaci n. LaTabla2muestralostiposdedatossoportadosporGrails,ascomo susrangos.

65

Captulo5.Dominiodeunaaplicacinweb

Tipo de dato Byte Short Integer Long Float Double Character String Boolean Date Object

Clase Numrico entero Numrico entero Numrico entero Numrico entero Numrico flotante Numrico flotante Alfanumrico Alfanumrico Lgico Cronolgico -128 a 127 -32,768 a 32,767

Rango 0 0 0

Valor por defecto

-2,147,483,648 a 2,147,483,647 -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 Precisin simple de acuerdo al estndar IEEE 7549 Precisin doble de acuerdo al estndar IEEE 754 0 a 65535 Tanto como la memoria de la JVM lo permita True, false A partir del 1 de enero de 1970 a las 00:00:00 GMT

0L 0.0f 0.0d '\u0000' null false. null null

Definida por el usuario Definido por el usuario

Tabla 2: Tipos de datos soportados por Grails.

Esimportanteconocerlosrangosdelostiposdedatosparalograr un mejor modelado y un mayor rendimiento de la aplicaci n. Por ejemplo, si se necesita representar la edad de una persona10, es imprcticoutilizaruntipodedato Integer.Enaplicacionesdondese manejaunacantidadpequeadedatos,elusode Byte e Integer de formaindistintanosereflejaenelrendimiento,peroenaplicaciones degranescaladondeseutilizanmillonesdedatos,elalmacenamiento de200,000registrosdeformamasivallevara4vecesmstiempocon undatoIntegerqueconundatodetipoByte.
9 Para un mayor tratamiento acerca de la precisin de nmeros flotantes, se sugiere visitar [IEE01] 10 La edad es tomada nicamente como un ejemplo ilustrativo. Generalmente la edad de una persona nunca es almacenada sino calculada. Lo ideal es almacenar la fecha de nacimiento.

66

Captulo5.Dominiodeunaaplicacinweb

Alfinaldelatablasedefineuntipodedato Object,EnGrails,este tipodedatoseutilizaparalacreacindeasociacionesentreobjetos. Las clases java.util.Date y java.lang.String son consideradas objetos peronoestndefinidosporelusuariodebidoaqueestnincluidasen elAPIdeJava.Aestasclasesselesdauntratamientoespecialen Java, Hibernate y Grails por ser tipos de datos ampliamente utilizados.Enelcasodelaclase Date,Hibernateseencargadehacer la equivalencia correspondiente sin necesidad de algn tipo de programacin adicional, independientemente del tipo de gestor de basesdedatosutilizado. Se recomienda utilizar los wrappers (clases envolventes) de Java [JAV02]paradatosprimitivosenlugardelosdatosprimitivospuros, yaqueenlaprcticasepresentanproblemasconlasbasesdedatos alutilizarreferenciasnulasquesondifcilesdedetectar.

5.3

Consistenciaeintegridad:validacindedatos

EnelarchivodelaclasededominiogeneradoporGrails,seincluye unclosurellamadoconstraints.Dentrodeesteclosureseescribenlas restricciones necesarias para los atributos. El uso de estas restricciones garantiza la integridad y consistencia de los datos ingresadosalaaplicacin. Dentro de la aplicacin, las restricciones se ven reflejadas en 2 partes: Enlageneracindelabasededatos(seccin4.4),

67

Captulo5.Dominiodeunaaplicacinweb

Enlavalidacindecamposalmomentodecrearunregistroen lainterfazgrfica.

Para el caso de la clase Profesor, se tienen las siguientes restricciones:


... 17.staticconstraints={ 18.folionullable:true,maxSize:15 19.paternonullable:true,maxSize:60 20.maternonullable:true,maxSize:60 21.nombrenullable:true,maxSize:60 22.curpnullable:true,maxSize:20 23.sexonullable:true,maxSize:1 24.emailnullable:true,maxSize:100 25.telefonoTrabajonullable:true,maxSize:50 26.telefonoCasanullable:true,maxSize:50 27.anioPlantillanullable:true 28.} ...

La primera restriccin a considerar es acerca del tratamiento de datosconvalornulo.Enmuchasbasesdedatos,laobligatoriedadde campos se maneja aplicando la restriccin de valor no nulo. Esto significa que un registro no puede ser introducido si un campo marcadocomononulotienelacondicincontraria(esdecir,esnulo). Grails permite la gestin de sta restriccin mediante la sentencia nullable:{true|false}. Algunas cadenas de caracteres pueden ser marcadas como no nulas, pero esto permite la introduccin de cadenas vacas. Para evitaresto,Grailsutilizalasentencia blank:{true|false}.Asimismo,la

68

Captulo5.Dominiodeunaaplicacinweb

longituddelascadenaspuedecontrolarsemediantelasentencia size: {min}..{max}. LaTabla3ylaTabla4muestrantodaslasrestriccionespermitidas enGrails.


Nombre blank Descripcin Verifica que una cadena no est vaca Ejemplo de uso nombre blank:false numeroTarjeta creditCard:true miMail email:true

creditCard Verifica que una cadena sea un nmero de tarjeta de crdito vlido. email inList matches max maxSize min minSize notEqual nullable range scale size Verifica que una cadena sea una direccin de correo electrnico vlida.

Verifica que el valor de un atributo est dentro de una colorPrimaro inlist:[rojo, coleccin de valores permitidos. amarillo, azul] Verifica que una cadena empate con una expresin regular dada. Verifica que un valor no supere el valor proporcionado. apellido matches:[a-zA-Z]+ precio max:1000

Verifica que el tamao de un valor no supere el valor curp maxSize:18 proporcionado. Verifica que un valor no se encuentre por debajo del valor proporcionado. Verifica que el tamao de un valor no se encuentre por debajo del valor proporcionado. Verifica que un atributo no sea igual al valor proporcionado. Habilita el uso de valores nulos. Por defecto, Grails no los permite. Acota el valor de una propiedad a los valores proporcionados Establece el nmero de decimales para valores flotantes Acota el tamao de una propiedad entre los valores proporcionados precio min:10 curp minSize:18 jedi notEqual:Palpatine password nullable:false adulto range:18..60 moneda scale:2 isbn size:13..13

Tabla 3: Restricciones utilizadas en Grails.

69

Captulo5.Dominiodeunaaplicacinweb

Nombre unique url validator

Descripcin Verifica que la propiedad no se repita en otros registros. Verifica que una cadena sea una URL vlida. Permite la creacin de validaciones personalizadas.

Ejemplo de uso username unique:true direccionWeb url:true numeroPar validator: { return (it % 2) == 0 }

Tabla 4: Restricciones utilizadas en Grails (continuacin).

Lasintaxisdevalidacinpermitecolocarmsdeunasentenciapor atributo, las cuales van separadas por comas. Asimismo, las restricciones pueden encerrarse entre parntesis para una mejor legibilidad.Porejemplo:
atributo(size:1..50,nullable:false,blank:false)

LadocumentacinoficialdeGrails11utilizaparntesisparailustrar losejemplosdecadaunadelasvalidaciones.

5.4

Estilizandolabasededatos

Talycomoseestudi enlaseccin4.4,almomentodeejecutarla aplicacin,Grailsgeneraoactualizalabasededatosenbasealas clasesdedominioexistentes.Paradeterminarelnombredelastablas ycampos,Grailsutilizalassiguientesconvenciones: Cadaclasededominioesrepresentadaporunatabla. Cadaatributodelaclasededominioesrepresentadoporun campo.


11 Es altamente recomendable que el usuario se familiarice con la documentacin de Grails y la utilice como referencia principal. La versin en lnea ms reciente se encuentra en [GRA02]. Cada distribucin de Grails contiene la documentacin en la carpeta doc/index.html.

70

Captulo5.Dominiodeunaaplicacinweb

Para todos los nombres, se utilizan nicamente letras minsculas.

Encasodequeelnombredeunaclaseoatributoconsistade2 omspalabras,cadaunadeellasesseparadaporungui n bajo.

Por cada tabla se generan los campos id y version de forma automtica.Elcampoidfuncionacomollaveprimaria,mientras que version lleva la cuenta de las actualizaciones hechas al registro.

La Tabla 5 muestra algunos ejemplos de las convenciones antes mencionadas.


Tipo Clase (Tabla) Clase (Tabla) Atributo (Campo) Atributo (Campo) Nombre en Grails Persona AccionRealizada nombre apellidoPaterno Nombre en la base de datos persona accion_realizada nombre apellido_paterno

Tabla 5: Algunas convenciones utilizadas en la generacin de la base de datos.

EsmuyfrecuentequelasconvencionesproporcionadasporGrails nosatisfaganlasnecesidadesdelaaplicacin.Enocasiones,sedebe desarrollar una aplicacin cuya base de datos ya existe, y generalmentestanosiguelasconvencionesantesmencionadas. Grailsproporcionalaopcindeestilizarlabasededatosatravsde unclosuredenominadomapping.Esteclosureutilizagranpartedelas convenciones utilizadas por Hibernate para realizar el mapeo ORM

71

Captulo5.Dominiodeunaaplicacinweb

entreclasesytablas. LaTabla6muestraalgunasdelasopcionesdeestilizacindebases dedatos.


Nombre id table column order sort Descripcin Personaliza la forma en que la llave primaria es generada. Ejemplo de uso id name:'titulo'

Personaliza el nombre de la tabla correspondiente table name:'catalogo_libros', a la clase. schema:'dbo' Personaliza la definicin de una columna. Personaliza el orden por defecto para el atributo. moneda column: "currency", sqlType: "char", length: 3 order 'desc'

Establece el atributo por defecto a tomar en sort 'fechaNacimiento' cuenta para la ordenacin de los resultados de las consultas. Personaliza el atributo version de la tabla correspondiente. version false

version

Tabla 6: Algunas opciones de estilizacin de la base de datos en Grails.

Enlaseccin4.2,semodelunatributollamadofolioparalaclase Profesor.Elatributofolioesnicoeirrepetible,porloqueesnecesario establecerlocomolallaveprimariadelatabladeprofesores. Para realizar un cambio en la base de datos, es recomendable detenerlaaplicacinutilizandoCtrl+Ccomosedescribeenlaseccin 4.4. Hecho esto, se procede a editar el archivo ubicado en grails app/domain/mx/edu/uaeh/promep/Profesor.groovy para agregar la estilizacinconelclosuremapping:
1.packagemx.edu.uaeh.promep 2. 3.classProfesor{

72

Captulo5.Dominiodeunaaplicacinweb
4. 5.//Atributos... 6.staticconstraints={ 7.//Restricciones... 8.} 9. 10.staticmapping={ 11.idname:'folio',generator:'assigned' 12.} 13.}

Por defecto, el nombre de la llave primaria es id y el tipo de generacines increment.Enel closure sesobreescribeelnombredel campo que corresponde al id a folio y se especifica su tipo de generacin a assigned (lnea 11), lo que significa que es responsabilidad del desarrollador la generacin y asignacin de la llaveprimaria. Comosiguientepaso,sedebeborrarlatabla profesor.EnMySQL, estoselograejecutandoelsiguientecomando:
mysql>droptableprofesor;

Ahora,sedebeponerenmarchalaaplicacincongrails runapp. GrailsyHibernategenerannuevamentelatabla profesor.Cuandose revisaenMySQL,seobtienelasiguienteestructuraqueyacontieneel foliocomollaveprimaria:


mysql>descprofesor; +++++++ |Field|Type|Null|Key|Default|Extra| +++++++ |folio|varchar(15)|NO|PRI|NULL|| |version|bigint(20)|NO||NULL||

73

Captulo5.Dominiodeunaaplicacinweb
|anio_plantilla|int(11)|YES||NULL|| |curp|varchar(20)|YES||NULL|| |email|varchar(100)|YES||NULL|| |materno|varchar(60)|YES||NULL|| |nombre|varchar(60)|YES||NULL|| |paterno|varchar(60)|YES||NULL|| |plantilla|bit(1)|NO||NULL|| |sexo|char(1)|YES||NULL|| |telefono_casa|varchar(50)|YES||NULL|| |telefono_trabajo|varchar(50)|YES||NULL|| +++++++ 12rowsinset(0.00sec)

5.5

Relacionesentreclasesdedominio

En la gran mayora de aplicaciones web con acceso a bases de datos,lasentidadesestnrelacionadasentres.Grailssoportalos3 tipos de relaciones existentes en el modelo relacional de base de datos: Unoauno, unoamuchos y muchosamuchos.Lassiguientes secciones adaptadas de la documentacin oficial de Grails [GRA02] tratancondetallecadaunadeellas. 5.5.1 Relacinunoauno

Una relacin uno a uno en Grails se logra mediante la siguiente nomenclatura:


1.classProfesor{ 2.statichasOne=[direccion:Direccion] 3.} 4.classdireccion{ 5.Profesorprofesor 6.}

74

Captulo5.Dominiodeunaaplicacinweb

Unaprofesortieneunayslounadireccin.Lapropiedad hasOne establece la relacin uno a uno entre la clase Profesor y la clase Direccion.Enlabasededatos,estosereflejar conunallavefornea enlatabladireccionenunacolumnallamadaprofesor_id. Parafortalecerlarelacin unoauno,esconvenienteagregaruna restriccindetipounique(lnea4):
1.classProfesor{ 2.statichasOne=[direccion:Direccion] 3.staticconstraints={ 4.direccionunique:true 5.} 6.} 7.classDireccion{ 8.Profesorprofesor 9.}

5.5.2 Relacinmuchosauno Unarelacinmuchosaunoeslamssencilladeimplementar,yes definidaagregandounapropiedadqueseadeltipodeotraclase.Por ejemplo:


1.classProfesor{ 2.Grupogrupo 3.} 4.classGrupo{ 5.}

Conestoselograunarelacinmuchosaunounidireccional,loque significaquelaclaseProfesorpuedeaccederasuatributo grupopero GruponopuedeaccederalaclaseProfesorquelacontiene.

75

Captulo5.Dominiodeunaaplicacinweb

Paralograrquelarelacinseabidireccional,bastaconagregarel atributobelongsTo(lnea5):
1.classProfesor{ 2.Grupogrupo 3.} 4.classGrupo{ 5.staticbelongsTo=[profesor:Profesor] 6.}

Con ello se establece que la clase Grupo pertenece a la clase Profesor.Elresultadodeestoesquesepuedeasociarunainstancia de Grupo aunainstanciadelaclase Profesor,ycuandoseejecuten accionesdeguardaryborraren sta ltima, stassevenreflejadas en Grupo. En otras palabras, las acciones de guardar y borrar se hacenencascada(deProfesoraGrupo):
1.newProfesor(grupo:newGrupo()).save() 2. 3.defp=Profesor.get(1) 4.p.delete()//ProfesoryGruposonborradas

Elejemploanteriorguardayborratanto ProfesorcomoGrupo.Cabe destacarqueaunqueseestableceunarelacinbidireccional,laaccin inversanoespermitida:


newGrupo(profesor:newProfesor()).save()//error

5.5.3 Relacinunoamuchos Una relacin uno a muchos se establece cuando una clase, por ejemplo Profesor,tienemuchasinstanciasdeotraclase,porejemplo Plazas. En Grails, dicha relacin se establece con la sentencia hasMany(lnea2):

76

Captulo5.Dominiodeunaaplicacinweb
1.classProfesor{ 2.statichasMany=[plazas:Plaza] 3.Stringnombre 4.} 5.classPlaza{ 6.Stringnombre 7.}

Loqueselograesuna relacin unoamuchosunidireccional,que significaquelaclaseProfesorpuedeaccederasucoleccindeplazas peroPlazasnopuedeaccederalaclaseProfesorquelacontiene. De forma automtica, Grails genera una propiedad de tipo java.util.SetdentrodelaclaseProfesorcuyonombreesplazas.Como ejemplodeusosetienelasiguientepiezadecdigo:
1.defp=Profesor.get(1) 2.p.plazas.each{ 3.printlnit.nombre 4.}

Elcomportamientoencascadaantesmencionadosehacepresente, conexcepcindelaaccindeeliminar,lacualnoserealizaamenos queunasentenciabelongsToseaespecificada:


1.classProfesor{ 2.statichasMany=[plazas:Plaza] 3.Stringnombre 4.} 5.classPlaza{ 6.staticbelongsTo=[profesor:Profesor] 7.Stringnombre 8.}

belongsTotambinestablecelarelacinbidireccionalentreProfesor

77

Captulo5.Dominiodeunaaplicacinweb

yPlaza. 5.5.4 Relacinmuchosamuchos El tratamiento de Grails para las relaciones muchos a muchos establecequeenambasclasesdebeexistirunasentencia hasManyy queunadelasclasesdebeserlapropietaria:
1.classProfesor{ 2.staticbelongsTo=Instituto 3.statichasMany=[institutos:Instituto] 4.Stringnombre 5.} 6.classInstituto{ 7.statichasMany=[profesores:Profesor] 8.Stringnombre 9.}

Lasentencia belongsTo establecequelaclase Instituto eslaclase propietariayquesehaceresponsabledelapersistenciadelaclase Profesor.Esta ltimanopuedegestionarlapersistenciade Instituto. Lasiguienteseccindecdigoguardaambasclases,yaqueeslaclase Institutoquienrealizalaaccinsave:
1.newInstituto(nombre:"ICBI") 2..addToProfesores(newProfesor(nombre:"Alejandro")) 3..addToProfesores(newProfesor(nombre:"Eduardo")) 4..save()

Enlasiguienteseccindecdigo, nicamentelaclase Profesor es guardada:


1.newProfesor(nombre:"Alejandro") 2..addToInstitutos(newInstituto(nombre:"ICBI"))

78

Captulo5.Dominiodeunaaplicacinweb
2..addToInstitutos(newInstituto(nombre:"ICSA")) 4..save()

Hasta el momento, la caracterstica de scaffolding en Grails no soporta las relaciones muchos a muchos. El desarrollador debe hacersecargodeestodeformamanual.

5.6

Resumen

Enestecaptulosetrataronadetallelascaractersticasquetienen las clases de dominio en Grails. La seleccin adecuada del tipo de datoparacadaatributo,lavalidacindelosmismos,laconsistenciay estilizacin de la base de datos, as como el tratamiento de los diferentestiposderelacionesentreclasessontpicoscrucialespara eldiseoptimodelalgicadenegocios. En el siguiente captulo se explora la persistencia de datos con GrailsyORM(GORM).

79

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

Captulo6

ModeloObjetoRelacionalenGrails(GORM)

Hoyenda,soncontadoslossitioswebquenocuentanconuna base de datos para el almacenamiento de la informacin que manejan. La persistencia de datos es una de las caracter sticas principalesdelosprogramasdecomputadora,yaquepermiteelusoy manipulacin de stos a corto y largo plazo. Las aplicaciones web desarrolladas con Grails no son la excepcin en el uso de esta tecnologa. Por ello, en las siguientes secciones se examina a profundidadelalmacenamientodedatosconGORM.

6.1

HibernateFrameworkyORM

Talcomosemencionenlaseccin3.6,Hibernateesunframework diseadoparafacilitarelusodebasesdedatosconJava.Elobjetivo de Hibernate es liberar al desarrollador de la escritura del 95% de sentencias SQL manejando el paradigma de la programacin orientadaaobjetos.EstoselogramediantelatecnologaORM(Object Relational Mapping, Mapeo ObjetoRelacional) y la abstraccin del gestordebasededatosdelaaplicacin. ORM utiliza mapeos de las clases de dominio de una aplicaci n hacindoloscorresponderconunabasededatosdetiporelacional. Conello,cadaclaseesrepresentadaporunatabla,cadaatributoes representado por un campo y cada instancia se representa con un registro. Deformamanual,eldesarrolladortienequeescribirlosarchivosde mapeo (cuya terminacin es *.hbm.xml) o las anotaciones

80

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

correspondientes en las clases de dominio para hacer la correspondencia ObjetoRelacional. Grails hace el mapeo de forma automticautilizandoconvenciones(seccin5.4,Tabla5)ypermitela estilizacindelosatributosdecadatabla(seccin 5.4, Tabla6).En casodequeyasetenganlosarchivosdemapeo,Grailspermitesu reutilizacin. A manera de ejemplo, si se tuviera que hacer manualmente el archivo de mapeo de una clase hipottica llamada Persona, se obtendralosiguiente:
1.<?xmlversion="1.0"encoding="UTF8"?> 2. <!DOCTYPE hibernatemapping PUBLIC "//Hibernate/Hibernate Mapping DTD 3.3.0//EN""http://hibernate.sourceforge.net/hibernatemapping3.0.dtd"> 4.<hibernatemapping> 5.<classname="clasehipotetica.Persona"table="PERSONA"> 6.<idcolumn="id"name="id"type="long"> 7.<generatorclass="native"/> 8.</id> 9.<propertycolumn="nombre"name="nombre"length=100 10.notnull="true"type=string/> 11.<propertycolumn="apellido_paterno"name="apellidoPaterno" 12.length=100notnull="true"type=string/> 13.<propertycolumn="apellido_materno"name="apellidoMaterno" 14.length=100notnull="true"type=string/> 15.<propertycolumn="fecha_nacimiento"name="fechaNacimiento" 16.notnull="true"type=timestamp/> 18.<propertycolumn="domicilio"name="domicilio"length=100 19.notnull="true"type=string/> 20.</class> 21.</hibernatemapping>

Puede notarse que la nomenclatura utilizada es XML, la cual en

81

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

ocasiones resulta incmoda para la lectura y mantenimiento de aplicaciones. Mediante la caracterstica archivodemapeo. Para lograr la abstraccin e independencia de la aplicacin del gestordebasededatosutilizado,Hibernateproporcionaundialecto para cada tipo de gestor. Al momento de hacer la conexin, se identificayaplicaellenguajeSQLpropiodedichogestor,liberandoal desarrolladordepreocuparseporlaportabilidad.Hibernatesoporta alrededorde40tiposdiferentesdegestoresdebasesdedatos. Convencin sobre Configuracin(seccin3.8.1),Grailseliminalanecesidaddeescribirel

6.2

ORMenGrails

Como se mencion en la seccin 3.8.3, Grails basa toda su persistencia de datos en Hibernate. Esto quiere decir que todo el conocimiento sobre este framework adquirido con anterioridad es aplicadoenGrails,alavezque ste ltimoagregafuncionalidadesy facilitaelusodeORMinclusosieldesarrolladornotieneexperiencia algunaenelusodeHibernate. AlcrearseunaclasededominioconGrails,seleagreganm todos depersistenciadeformadinmicaeimplcita.Lafuncionalidaddelos mtodos van desde las 4 operaciones bsicas CRUD (create, read, update y delete), consultas con mtodos dinmicos, consultas estticas mediante Criteria, hasta consultas con HQL (Hibernate QueryLanguage).Elrestodelcaptulodetalladichastecnologas.

82

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

6.3

Mtodoscomunesatodaslasclasesdedominio

En toda aplicacin web con conexin a base de datos, las operaciones CRUD son las primeras en codificarse y las ms utilizadas.ElusoenGrailsdestasoperacionesesbastantesencillo. 6.3.1 Create Para generar unregistroenlabasededatos,bastacontener la instanciadeunaclasededominioyllamaralmtodosave:
1.Profesorprofesor=newProfesor( 2.nombre:'Alejandro', 3.paterno:'Garca', 4.materno:'Granados', 5.curp:'GAGA870301HDFRRL09', 6.sexo:'M') 6.profesor.save()

Elmtodosavepuederecibirparmetros.LaTabla7describecada unodeellos.
Nombre validate flush failOnError deepValidate Descripcin Bandera que determina si se lleva a cabo la validacin de restricciones de la instancia. Bandera que determina que si el objeto se guarda inmediatamente o no. Bandera que determina si se arroja una excepcin si la validacin de la instancia falla. Bandera que determina si la validacin es en cascada en las asociaciones de la instancia. Ejemplo de uso profesor.save(validate:true) profesor.save(flush:true) profesor.save(failOnError:true) profesor.save(deepValidate:true)

Tabla 7: Parmetros del mtodo save. Elmtodosavenoguardaunainstanciainmediatamenteamenos quelabandera flush est activada.Pordefecto,elmtodoregresala

83

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

instanciaguardada.Perosiocurrealgnerror,devuelvenulo. 6.3.2 Read LaobtencinderegistrosdelabasededatosconGrailsselogra mediantevariosmtodos.Unodeelloseselmtodoget:


Profesorprofesor=Profesor.get(23)

Elmtodo get recibecomoparmetroeliddelregistrodeseado.Si sedeseanobtenerinstanciasdeslolectura,seutilizaelmtodoread:


Profesorprofesor=Profesor.read(23)

Un mtodo interesante que permite obtener varias instancias es getAll:


deflistaProfesores=Profesor.getAll(2,1,3) deflistaProfesores=Profesor.getAll([1,2,3]) deflistaProfesores=Profesor.getAll()

Elmtodo getAll puedeutilizarsede3formas.Laprimeradeellas recibe los id's de las instancias deseadas separados por comas. La particularidadde stemtodoesquesusargumentossondelongitud variable,esdecir,puederecibircualquiernmerodeid's.Lasegunda formarecibeunalista,ylatercera,alnorecibirparmetros,devuelve todaslasinstanciasdelabasededatos. UnmtodomuyutilizadoenGrailsenlacapadecontroladoreses list, el cual devuelve una lista de todos los objetos de la clase de dominio.
1.deflistaProfesores=Profesor.list() 2.deflistaProfesores=Profesor.list(params)

Existen2versionesdeestemtodo.Laprimeradevuelvetodaslas

84

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

instanciasexistentes,mientrasquelasegundarecibeunmapacon diversosparmetrosdepaginacinyordenamiento: max,quelimitaelmximoderegistros, offset,quedeterminaelregistrodepartidaparalaconsulta, order, que indica el orden de los registros (ascendente o descendente), sort, que indica el atributo tomado como referencia para el ordenamiento. 6.3.3 Update El mtodo save es utilizado en Grails para crear y actualizar instanciasdeclasesdedominio.Porlotanto,lasreglasdescritasen laseccin6.3.1aplicanparalaactualizacinderegistros. 6.3.4 Delete ParaeliminarunainstanciaenGrails,seutilizaelmtododelete:
1.defprofesor=Profesor.get(1) 2.profesor.delete()

Paraqueelmtodofuncione,lainstanciadebehaberseobtenidode labasededatos,esdecir,tienequeserpersistente.Encasocontrario seobtieneunerror. El mtodo delete recibe un parmetro, flush, que funciona tal y comosedescribeenla Tabla7,sloqueenvezdeserguardadao actualizada,lainstanciaseeliminainmediatamente.

85

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

6.4

Mtodosdinmicos

Adems de las operaciones CRUD, una aplicacin con acceso a base de datos realiza consultas. Grails ofrece la utilizaci n de las mismas mediante una tecnologa denominada Dynamic Finders (buscadores dinmicos o mtodos dinmicos). La caracterstica principaldeestosmtodosesqueelusuarionolosimplementade formadirecta,sinoqueconbasealascaractersticasdelaclasede dominio stos pueden ser invocados. Para ilustrar su uso, se consideralaestructuradelaclaseProfesor:
1.classProfesor{ 2. 3.Stringnombre 4.Stringpaterno 5.Stringmaterno 6.Stringcurp 7....

Lossiguientesmtodosdinmicospuedenserinvocados:
1.defp=Profesor.findByNombre("Anakin") 2.p=Profesor.findByNombreAndPaterno("James","Gosling") 3.p=Profesor.findAllByNombreLike("%Roberto%") 4.p=Profesor.findAllByNombreIlike("%Roberto%") 5.p=Profesor.findAllByNombreNotEqual("Alicia") 6.p=Profesor.countByCurpIsNull() 7.p=Profesor.countByPaternoOrMaterno( 8."Gmez","Hernndez")

Grails utiliza un mecanismo interno que en tiempo de ejecucin ejecutalaconsultaformadaporelmtododinmico,loquesignifica que ningn mtodo es implementado en s, sino que todos son ejecutados en una sola consulta al estilo de Hibernate. La sintaxis

86

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

generaldeunmtododinmicoeslasiguiente:
[nombreClase].(findBy|findAllBy|countBy)([atr][comp][op])?[atr][comp]

Donde: nombreClase: la clase de dominio que llama al mtodo dinmico findBy|findAllBy|countBy:eltipodeconsultaarealizar. atr:elnombredelatributodelaclasededominio comp:eltipodecomparadorautilizar. op:eltipodeoperadorautilizar.

La Tabla 8 y la Tabla 9 muestran los tipos de comparadores y operadoresdisponiblesenlosmtodosdinmicos.


Nombre LessThan LessThanEquals GreaterThan GreaterThanEquals Between Like ILike IsNotNull IsNull Not Equal Comparador Comparador Comparador Comparador Comparador Comparador Comparador Comparador Comparador Comparador Comparador Tipo Tipo de consulta soportado countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy countBy

Tabla 8: Comparadores y Operadores soportados por los mtodos dinmicos.

87

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

Nombre NotEqual And Or InList Comparador Operador Operador Comparador

Tipo

Tipo de consulta soportado countBy, findAllBy, findBy countBy, findAllBy, findBy countBy, findAllBy, findBy findAllBy, findBy

Tabla 9: Comparadores y Operadores soportados por los mtodos dinmicos (continuacin). Lasentencia Not esutilizadaparahacerconsultassobredatosde tipo booleano. Por ejemplo, si existiera un atributo suscrito de tipo booleano en la clase Profesor, un mtodo dinmico quedara de la siguientemanera:
1.p=Profesor.findSuscritoByNombre("Roberto") 2.p=Profesor.findNotSuscritoByNombre("Roberto")

Una limitacin de los mtodos dinmicos es que solo pueden utilizarse2atributosdelaclasededominioparaconstruirse.Parala realizacindeconsultasqueinvolucrenmsde2atributos,seutiliza latecnologadeCriteriaoHQL.

6.5

Realizacindeconsultasorientadasaobjetos:Criteria

Criteria esunatecnologaderealizacindeconsultasorientadaa objetos, lo cual significa que se utilizan mtodos en lugar de sentenciasintroducidasmediantecadenas.Unejemplotomadodela documentacinoficialdeGrailseslasiguiente:
1.defc=Profesor.createCriteria() 2.defresults=c{ 3.between("anioPlantilla",500,1000) 4.eq("nombre","Alejandro") 5.or{

88

Captulo6.ModeloObjetoRelacionalenGrails(GORM)
6.like("paterno","Fred%") 7.like("paterno","Barney%") 8.} 9.maxResults(10) 10.order("materno","desc") 11.}

PrimerosedebecrearunobjetodetipoCriteria,elcualseobtiene llamando al mtodo createCriteria o withCriteria de la clase de dominio. Posteriormente las restricciones se escriben mediante un DSL. Las restricciones corresponden al API de Hibernate, especficamente de la clase Restrictions [HIB02]. En el ejemplo mostrado se buscan los registros que cumplan con las siguientes restricciones: SuatributoanioPlantillaesteentre500y1000. SuatributonombreseaigualaAlejandro. SuatributoparternocomienceconFredoBarney. Elnmeromximoderegistroses10. Los resultados se ordenan en forma descendente tomando el atributomaternocomoreferencia. Pordefecto,todaslasrestriccionessonutilizadasconeloperador lgicoAND.Sisedeseautilizarotrotipodeoperadorlgico,sedeben agrupar.Elejemploanteriormuestralaagrupacinde2restricciones likemedianteeloperadorlgicoOR. PuedeutilizarseCriteriaconasociacionesentreobjetos.Suponiendo quesetienelasiguienteclasededominio:

89

Captulo6.ModeloObjetoRelacionalenGrails(GORM)
1.classProfesor{ 2.... 3.statichasMany=[asistencias:Asistencia] 4.... 5.}

ParautilizarelatributotransactionsenelDSLdeCriteria,sedebe utilizarunnodoconelnombredelatributo:
1.defc=Profesor.createCriteria() 2.defnow=newDate() 3.defresults=c.list{ 4.asistencias{ 5.between('date',now10,now) 6.} 7.}

Este ejemplo busca todas las instancias de Profesor que tengan asistenciasrealizadasdurantelos ltimos10das.Puedenotarseel uso del mtodo list en el objeto c. Criteria soporta 5 mtodos diferentes,siendo list elmtodoutilizadopordefectoencasodeno especificaralguno.LaTabla10describestosmtodos.
Mtodo list get scroll count listDistinct Descripcin Regresa todos los resultados que coincidan con las restricciones. Mtodo utilizado por defecto. Regresa una lista con un solo resultado. Regresa una lista desplazable. Regresa el nmero de resultados. Regresa un lista con resultados no repetidos.

Tabla 10: Mtodos soportados por Criteria. Para un tratamiento detallado del uso de Criteria, se sugiere consultarelAPIdeHibernateyladocumentacinoficialdeGrails.

90

Captulo6.ModeloObjetoRelacionalenGrails(GORM)

6.6

HibernateQueryLanguaje(HQL)

Para la realizacin de consultas similares a SQL, Hibernate proporciona su propio lenguaje denominado HQL (Hibernate Query Language)elcualesmuyparecidoa SQL,conladiferenciadeque HQL es completamente orientado a objetos. Una excelente introduccin a HQL puede ser encontrada en su documentacin oficial[HIB03]. Grailsproporciona3mtodosparalarealizacindeconsultasHQL. LaTabla11describecadaunodeellos.
Mtodo findAll find executeQuery Descripcin Regresa todos los resultados que coincidan con la consulta. Regresa una lista con un solo resultado. Permite la ejecucin de una sentencia HQL que no necesariamente regresa instancias de una clase de dominio.

Tabla 11: Mtodos en Grails para el uso de HQL. EjemplosdeconsultasHQLsonlossiguientes:


1.defresultados=Profesor.findAll( 2."fromProfesoraspwherep.nombrelike'Ale%'")

HQLconelusodeparmetrosposicionales:
1.defresultados=Profesor.findAll( 2."fromProfesoraspwherep.nombrelike?",["Ale%"]) 3.defgrupo=Grupo.findByNombre("94") 4.defprofesores=Profesor.findAll( 5."fromProfesoraspwherep.grupo=?",[grupo])

HQLconelusodeparmetrosnombrados:
1.defresultados=Profesor.findAll( 2."fromProfesoraspwherep.nombrelike:searchorp.nombre"+ 3."like:search",[search:"Ale%"])

91

Captulo6.ModeloObjetoRelacionalenGrails(GORM)
4.defgrupo=Grupo.findByNombre("94") 5.defprofesores=Profesor.findAll( 6."fromProfesoraspwherep.grupo=:grupo",[grupo:grupo])

Una caracterstica de HQL que es muy utilizada en Grails es la paginacin y el ordenamiento de resultados. Los mtodos findAll y executeQuerysoportanunparmetroextraparaintroducirpaginacin mediantemaxyoffset:
1.defresultados=Profesor.findAll( 2."fromProfesoraspwherep.nombrelike'Ale%'"+ 3."orderbyp.nombreasc",[max:10,offset:20]) 4.results=Profesor.executeQuery( 5."selectdistinctp.nombrefromProfesorpwherep.nombre=:nombre", 6.[nombre:'Alejandro'],[max:10,offset:5])

6.7

Resumen

A lo largo de este captulo se mostraron las principales caractersticasdeGORM.Lapersistenciadedatosenunaaplicacin webesunadelosmdulosmsutilizados,porloqueGrailslededica una parte considerable de su entorno. En el siguiente captulo se hablaacercadelacapadepresentacinysuinteraccinconlalgica denegocios,ademsdeaplicarloaprendidodelasclasesdedominio yGORM.

92

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

Captulo7 CapadepresentacinWeb:Controladores yGroovyServerPages


Paralograrlainteraccinentreunaaplicacinwebylosusuarios finales,seutilizanInterfacesGrficasdeUsuario(GUI,porsussiglas en ingls). Las primeras GUI contenan elementos simples y poco estticos,peroconeladvenimientodeWeb2.0todocambi deforma radical.EscomnencontrarGUI'sconelementosricosencontenido multimedia, animaciones, interactividad asncrona y sobre todo, intuitivasalusuario.YanobastaconsaberHTMLparadesarrollar GUI's de alta calidad. Con el surgimiento de HTML 5, Ajax y JavaScriptsepostulancomolastecnologasdepresentacindemayor usoenlaWeb. Grails no es la excepcin al uso de stas tecnologas. En ste captulosetrataadetallelaconexindelalgicadenegociosyla capa de presentacin mediante controladores, asi como el uso de HTML,JavaScriptyAjaxparaeldesarrollodelasvistas.

7.1

Generacindecontroladores

En la seccin 4.3 se utiliz el comando createcontroller para la creacindecontroladores.Aestosselesagreg lapropiedadscaffold =true.Estogenera deformadinmica elcdigonecesarioparalos controladoresylasvistas.Ciertamente,soncontadaslasaplicaciones que satisfagan sus requerimientos de GUI con los controladores y vistas que Grails ofrece, por lo que es necesario generar el cdigo paramodificarlo.

93

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

Para la generacin de los archivos correspondientes, se utiliza el comandogeneratecontroller:


grailsgeneratecontrollermx.edu.uaeh.promep.Profesor grailsgeneratecontrollermx.edu.uaeh.promep.Grupo grailsgeneratecontrollermx.edu.uaeh.promep.Plaza

Laejecucindeestoscomandosgeneranlossiguientesarchivos(se omitenlosarchivosdeprueba):
BDPromep/ |grailsapp `controllers `mx/edu/uaeh/promep |ProfesorController.groovy |GrupoController.groovy `PlazaController.groovy

Se utiliza el principio de Convencin sobre Configuracin (seccin 3.8.1)paralacreacindeloscontroladores.

7.2

Anlisisdetalladodeloscontroladores

Los archivos de los controladores generados poseen closures que permitenlainteraccindelasinterfacesgrficasdeusuarioconla lgicadenegocios.Acontinuacin,sedescribendetalladamentecada uno de estos closures. Se toma como ejemplo el controlador de la claseProfesor. 7.2.1 indexylist

Todocontroladortieneunaaccinpordefecto,lacualesnombrada

94

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

index.CuandosehaceunapeticinalservidorconlasiguienteURL: http://localhost:8080/BDPromep/profesor obien http://localhost:8080/BDPromep/profesor/index Elclosureindexesinvocado.Esteclosuretienelasiguienteforma:


1.defindex={ 2.redirect(action:"list",params:params)

3.}

Puede observarse que index redirecciona a list enviando los parmetrosqueelservidorenvaoriginalmenteaindex.Elclosurelist tienelasiguienteforma:
1.deflist={ 2.params.max=Math.min(params.max?params.int('max'):10,100) 3.[profesorInstanceList:Profesor.list(params), 4.profesorInstanceTotal:Profesor.count()] 5.}

La variable params es una variable de tipo java.util.Map que contiene los nombres de los parmetros como llave y sus valores correspondientes como valor. Estos parmetros provienen de los valoresenviadosjuntoconlaURL.Porejemplo: http://localhost:8080/BDPromep/profesor/list?max=10&offset=10 EnestaURLlosparmetrosenviadossonmaxyoffset,amboscon unvalorde10. Enlalnea2,siparamscontienelallavemax,seconservasuvalor, encasocontrario,seestableceen10.Elvalormximopermitidoes

95

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

100,estoconelfindeevitardesbordamientosdelamemoriaenla aplicacinweb. Laslneas3y4representanunmapaenGroovyquecontienelas variables de salida dirigidas a la vista (en este caso, views/profesor/list.gsp).Estemapaseconocecomoelmodelo(M)en elpatrndearquitecturaMVCmencionadoenlaseccin4.3.Seenva lalistadepersonasparametrizada(encasodeexistirparmetros)yel total de instancias existentes, todo esto a travs de las variables profesorInstanceList y profesorInstanceTotal,respectivamente.Lavista seencargaderenderizarelcontenidodeestasvariables. 7.2.2 create CuandosehaceunapeticinalservidorconlasiguienteURL: http://localhost:8080/BDPromep/profesor/create Elclosurecreateesinvocado.Esteclosuretienelasiguienteforma:
1.defcreate={ 2.defprofesorInstance=newProfesor() 3.profesorInstance.properties=params 4.return[profesorInstance:profesorInstance] 5.}

Se define una variable llamada profesorInstance de tipo Profesor (lnea 2). Los atributos de esta instancia son inicializados con los parmetrosrecibidosenlapeticinHTTP.Laprimeravezquesellama a create notienemuchosentidoutilizarlosparmetrossimplemente porquenoexisten,peroesimportantecuandoserealizalavalidaci n de datos en el closure save, como se ver en breve. La instancia

96

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

inicializada es enviada a la vista correspondiente (lnea 4): views/profesor/create.gsp, la cual renderiza el contenido de profesorInstance. 7.2.3 save CuandosehaceunapeticinalservidorconlasiguienteURL: http://localhost:8080/BDPromep/profesor/create seobtieneunaGUIsimilaralamostradaenlaFigura9.Dentrodel cdigoHTML,existeunformularioqueest definidodelasiguiente forma:
<formaction="/BDPromep/profesor/save"method="post">

Al momento de hacer clic en Crear, el closure save es invocado. Esteclosuretienelasiguienteforma:


1.defsave={ 2.defprofesorInstance=newProfesor(params) 3.if(profesorInstance.save(flush:true)){ 4.flash.message="${message(code:'default.created.message', 5.args:[message(code:'profesor.label',default:'Profesor'), 6.profesorInstance.id])}" 7.redirect(action:"show",id:profesorInstance.id) 8.} 9.else{ 10.render(view:"create", 11.model:[profesorInstance:profesorInstance]) 12.} 13.}

Nuevamente, se define una variable llamada profesorInstance de tipo Profesor inicializada con los parmetros de entrada (lnea 2).

97

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

Grails intenta guardar el registro en la base de datos (lnea 3). Al momentodeinvocarelmtodosave,serealizalavalidacindedatos especificadaenelclosureconstraintsdelaclasededominio.Sinohay errores,seenvaunmensajedenotificacinalusuariomediantela variable flash.message (lneas 4, 5 y 6). El mensaje enviado est especificado en los archivos i18n/messages_XX.properties con la etiqueta default.created.message. En el archivo messages.properties, seencuentralosiguiente:
default.created.message={0}{1}created

El mensaje recibe 2 parmetros. En el closure save se enva el mensaje con el cdigo profesor.label, que en caso de no existir, el mensajepor defectoes Profesor.ElsegundoparmetroeselIDdel registro recin creado. Un ejemplo del mensaje formado puede apreciarseenlaFigura10. La variable flash es una variable especial. De acuerdo a la documentacindeGrails: El objeto flash es esencialmente un mapa que puede utilizarseparaguardarparejaskeyvalue.Estosvaloresson almacenados de forma transparente dentro de la sesi n y borradasalfinaldelasiguientepeticin Enelclosuresavesecreaunavariablemessageysealmacenaen flash.Posteriormenteseredireccionaalclosure showysemandaelid como modelo (lnea 7). Puede notarse que no se envia la variable flash,peroexistedebidoaquesobrevivealasesinactual(save)ya

98

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

lasiguiente(show).Esporesoquealrenderizarelarchivo show.gsp enlaFigura10elmensajeaparece. Silavalidacindedatosnoesexitosa,seinvocaalmtodo render. Semuestralavistaconelnombrede createyseenvalainstanciade laclasecomomodelo(lneas11y12). 7.2.4 show CuandosehaceunapeticinalservidorconlasiguienteURL: http://localhost:8080/BDPromep/profesor/show/1 Elclosureshowesinvocado.Esteclosuretienelasiguienteforma:
1.defshow={ 2.defprofesorInstance=Profesor.get(params.id) 3.if(!profesorInstance){ 4.flash.message="${message(code:'default.not.found.message', 5.args:[message(code:'profesor.label', 6.default:'Profesor'),params.id])}" 7.redirect(action:"list") 8.} 9.else{ 10.[profesorInstance:profesorInstance] 11.} 12.}

En la lnea 2 se define una variable llamada profesorInstance de tipoProfesor,cuyainstanciaseconstruyeconunallamadaalmtodo getdelaclaseProfesor.Elparmetroquerecibeestemtodoproviene deunparmetroespecialcontenidoenlaURL.Esteparmetrorecibe el nombre de id y es el valor final de la URL justo despus de la

99

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

palabrashow(enelejemplomostradoes1). Enlalnea3,silainstancianoesencontradaenlabasededatos, se enva un mensaje en la variable flash con el cdigo default.not.found.messagecondiversosargumentos(lneas4,5y6)y seredireccionaalaaccinlist(lnea7).Silainstanciaesencontrada, seenvacomomodeloalarchivoshow.gspyserenderiza. 7.2.5 edit Laparteinferiordela Figura10 muestra2botones: Edit y Delete. Estosbotonespermiteneditaryeliminarelregistrorespectivamente. Analizando el cdigo fuente de la pgina web se encuentra lo siguiente:
1.<formaction="/BDPromep/profesor/index"method="post"> 2.<inputtype="hidden"name="id"value="1"id="id"/> 3.<spanclass="button"> 4.<inputtype="submit"name="_action_edit"value="Edit" 5.class="edit"/> 6.</span> 7.<spanclass="button"> 8.<inputtype="submit"name="_action_delete"value="Delete" 9.class="delete" 10.onclick="returnconfirm('Areyousure?');"/> 11.</span> 12.</form>

Deformainterna,Grailsinvocaalasacciones edit y delete sise hace clic en los botones respectivos. El closure para edit tiene la siguienteforma:
1.defedit={

100

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
2.defprofesorInstance=Profesor.get(params.id) 3.if(!profesorInstance){ 4.flash.message="${message(code:'default.not.found.message', 5.args:[message(code:'profesor.label', 6.default:'Profesor'),params.id])}" 7.redirect(action:"list") 8.} 9.else{ 10.return[profesorInstance:profesorInstance] 11.} 12.}

Comopuedeobservarse,eselmismocdigoparaedityparashow. Laprincipaldiferenciaradicaenlapginafinalqueserenderizasila instancia de la clase es encontrada en la base de datos, la cual dependedelnombredelaaccinejecutada.Asimismo,elidutilizado para la bsqueda del registro se obtiene mediante parmetros normalesenedit(NteselaentradadetipohiddenenelcdigoHTML enlalnea2)ynomedianteelparmetroespecialutilizadoenshow. 7.2.6 update ElformulariomostradoenlaFigura11tiene2botonesenlaparte inferior:UpdateyDelete.

101

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

Figura 11: Formulario de edicin de datos.

AlhacerclicenUpdate,sellamaalclosureconelmismonombre. Elcdigodelcontroladorparaestaaccineselsiguiente:
1.defupdate={ 2.defprofesorInstance=Profesor.get(params.id) 3.if(profesorInstance){ 4.if(params.version){ 5.defversion=params.version.toLong() 6.if(profesorInstance.version>version){ 7. 8.profesorInstance.errors.rejectValue("version", 9."default.optimistic.locking.failure", 10.[message(code:'profesor.label', 11.default:'Profesor')]asObject[], 12."AnotheruserhasupdatedthisProfesorwhile"+ 13."youwereediting" 14.)

102

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
15.render(view:"edit", 16.model:[profesorInstance:profesorInstance]) 17.return 18.} 19.} 20.profesorInstance.properties=params 21.if(!profesorInstance.hasErrors()&& 22.profesorInstance.save(flush:true)){ 23.flash.message="${message(code:'default.updated.message', 24.args:[message(code:'profesor.label', 25.default:'Profesor'), 26.profesorInstance.id])}" 27.redirect(action:"show",id:profesorInstance.id) 28.} 29.else{ 30.render(view:"edit", 31.model:[profesorInstance:profesorInstance]) 32.} 33.} 34.else{ 35.flash.message="${message(code:'default.not.found.message', 36.args:[message(code:'profesor.label',default:'Profesor'), 37.params.id])}" 38.redirect(action:"list") 39.} 40.}

Se define una variable llamada profesorInstance de tipo Profesor, cuyainstanciaseconstruyeconunallamadaalmtodogetdelaclase Profesor(lnea2).Elparmetroquerecibeestemtodoprovienedeun campo de entrada de tipo hidden contenido en los parmetros de entrada.Silainstanciaesencontrada(lnea3),severificaquealguien msnohayamodificadoelregistroaactualizaratravsdelatributo

103

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

version (lneas4y5).Sielvalorcontenidoenlainstanciaesmayor queelvalorobtenidoenlosparmetrosdeentrada(lnea6),elregistro noesactualizadoyseenvaunmensajedeerroralusuarioatravs delavariableerrorsdelainstancia(lneas8a17). Silaversinescorrecta,seprocedeainicializarlosatributosdela instancia con los parmetros de entrada recibidos mediante el formulario(lnea20).Apartirdeestepuntoseprocededelamisma formadescritaenlaseccin7.2.3.Serealizavalidacindedatosycon basealresultadoobtenidoseenvaalavistacorrespondiente.Sila instancia no es encontrada, se notifica al usuario con un mensaje alojadoenlavariableflash. 7.2.7 delete ElsegundobotndelformulariomostradoenlaFigura10invocaa la accin delete. La estructura del closure correspondiente a esta accineslasiguiente:
1.defdelete={ 2.defprofesorInstance=Profesor.get(params.id) 3.if(profesorInstance){ 4.try{ 5.profesorInstance.delete(flush:true) 6.flash.message="${message(code:'default.deleted.message', 7.args:[message(code:'profesor.label', 8.default:'Profesor'), 9.params.id])}" 10.redirect(action:"list") 11.} 12.catch(org.springframework.dao.

104

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
13.DataIntegrityViolationExceptione){ 14.flash.message="${message( 15.code:'default.not.deleted.message', 16.args:[message(code:'profesor.label', 17.default:'Profesor'), 18.params.id])}" 19.redirect(action:"show",id:params.id) 20.} 21.} 22.else{ 23.flash.message="${message(code:'default.not.found.message', 24.args:[message(code:'profesor.label',default:'Profesor'), 25.params.id])}" 26.redirect(action:"list") 27.} 28.}

Se define una variable llamada profesorInstance de tipo Profesor, cuyainstanciaseconstruyeconunallamadaalmtodogetdelaclase Profesor(lnea2).Elparmetroquerecibeestemtodoprovienedeun campo de entrada de tipo hidden contenido en los parmetros de entrada.Silainstanciaesencontrada,seprocedeasueliminaci n (lnea3).Si staesexitosa,seenvaunmensajeconlavariable flash yseredireccionaa list (lneas6a10).Encasodequeocurraalgn errorenlaeliminacin,seenvaunmensajeconlavariableflashyse redireccionaashow(lneas14a19).Silainstancianoesencontrada, senotificaalusuarioconunmensajeyseredireccionaa list (lneas 23a26).

105

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

7.3

Generacindelasvistas

Para la generacin de los archivos correspondientes, se utiliza el comandogenerateviews:


grailsgenerateviewsmx.edu.uaeh.promep.Profesor grailsgenerateviewsmx.edu.uaeh.promep.Grupo grailsgenerateviewsmx.edu.uaeh.promep.Plaza

Laejecucindeestoscomandosgeneranlossiguientesarchivos(se omitenlosarchivosdeprueba):
BDPromep/ |grailsapp `views |profesor ||create.gsp ||edit.gsp ||list.gsp |`show.gsp |grupo ||create.gsp ||edit.gsp ||list.gsp |`show.gsp `plaza |create.gsp |edit.gsp |list.gsp `show.gsp

Nuevamente, se utiliza el principio de Convencin sobre

106

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

Configuracin(seccin3.8.1)paralacreacindelasvistas.

7.4

Plantillasusadasparalageneracindecontroladoresy vistas

La tcnica de scaffolding y los comandos generate* utilizan una serie de plantillas como base para la generacin del cdigo de los controladoresylasvistas.Comosehamencion conanterioridad,es raralaaplicacinwebqueutilicelasvistasycontroladoresqueGrails generadeformaautomtica,porloquesehacenecesarioaccederal cdigo (en caso de estar utilizando scaffolding) para modificarlo de acuerdoalasnecesidadesdelaaplicacin.Alutilizarloscomandos generate*,seobtienedichocdigo.Puededarseelcasodequeexistan muchas clases de dominio y por lo tanto que se generen muchos archivosfuente,yesbastantecomnqueelcdigotengasimilitudes entresi,porloquesehacetediosalatareademodificarcadaunode losarchivosparalograrunmismoresultado. Grailspermiteobtenerelcdigofuentedelasplantillasutilizadas en la generacin de controladores y vistas. Si al momento de desarrollarunaaplicacinwebsepresentalasituacinmencionada en el prrafo anterior, la modificacin de las plantillas es una excelente opcin para la automatizacin de cdigo estilizado por el desarrollador. Elcomandoquepermiteobtenerlasplantillaseselsiguiente:
>grailsinstalltemplates

Laejecucindedichocomandogeneralasiguienteestructurade

107

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

archivosydirectorios:
BDPromep/src |groovy |java `templates |artifacts ||Controller.groovy ||DomainClass.groovy ||Filters.groovy ||hibernate.cfg.xml ||Script.groovy ||Service.groovy ||tagLib.groovy ||Tests.groovy |`WebTest.groovy |scaffolding ||Controller.groovy ||create.gsp ||edit.gsp ||list.gsp ||renderEditor.template |`show.gsp `war `web.xml

Las plantillas son instaladas en src/templates. Existen 3 tipos: artifacts, que contienen las plantillas utilizadas por diversos comandos de Grails para crear controladores, clases de dominio,

108

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

filtros,scripts,servicios,taglibsytests;scaffolding,quecontienenlas plantillasdelasvistas,generacindecontroladoresyrenderizacinde elementos en los GSP; y war, que contiene el archivo web.xml, elemento clave enlasaplicacionesweb hechascon Java Enterprise Edition. Se recomienda ampliamente explorar cada uno de estos archivosparaconocerelfuncionamientodelasplantillasyexplotaral mximoestafuncionalidad.

7.5

GroovyServerPages

Los archivos correspondientes a las vistas en Grails utilizan la tecnologadenominada GroovyServerPages o GSP.GSPessimilara JavaServerPages (JSP),conladiferenciadequeGSPutilizaGroovy enlugar deJavacomosu lenguajebaseyGSPesmspoderosoe intuitivo. AligualqueunJSP,unGSPpermitelainclusindirectadecdigo mediantelasiguientesintaxis:
<%now=newDate()%>

ElcdigoincrustadodentrodeunJSPesdenominado scriptlet.Sin embargo, actualmente se considera una mala prctica de programacinutilizarlos.Comolanecesidaddeasociar la lgica de negociosnodesaparece,seutilizaformasmselegantesparalograr esteobjetivo:Expresionesytaglibs.

7.6

Expresiones

Groovy permite el uso de expresiones para la renderizacin de

109

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

cdigo Groovy en un archivo GSP. La sintaxis de una expresin es idnticaalautilizadaenJSP:


1.<html> 2.<body> 3.Hello${params.name} 4.</body> 5.</html>

Todaexpresinestencerradaentre${...}.Elusodeexpresionesen lasvistasgeneradasporGrailsesmuyextendido.Ejemplodeelloesel archivoviews/profesor/create.gsp:


1.<g:iftest="${flash.message}"> 2.<divclass="message">${flash.message}</div> 3.</g:if> 4.<g:hasErrorsbean="${profesorInstance}"> 5.<divclass="errors"> 6.<g:renderErrorsbean="${profesorInstance}"as="list"/> 7.</div> 8.</g:hasErrors>

En la seccin 7.2.2 se menciona que algunas variables son renderizadasalavista.Lasexpresionespermitendicharenderizaci n al manipular el valor que contienen. Las expresiones pueden renderizarsedeformadirectaoserutilizadaspor taglibs,loscualesse explicanmsadelante.EscomnqueelvalorarenderizarenunGSP sea una llamada al mtodo toString de la variable contenida en la expresin.Tcnicamente,sielvalortoStringdeunavariablecontiene cdigo HTML, ste se renderiza en la pgina final, lo cual puede provocarresultadosinesperados.Paraevitarlo,sesugiereagregarla siguientepropiedadenelarchivograilsapp/conf/Config.groovy:

110

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
grails.views.default.codec='html'

7.7

Taglibs

UnadelascaractersticasmspoderosasdeGSPessubiblioteca detaglibs.Grailsofreceunaampliagamadefuncionalidadesqueel desarrolladorpuedeutilizarparadiversastareas,alavezquepuede desarrollar sus propios taglibs si los que estn por defecto no satisfacensusnecesidades. 7.7.1 Tomadedecisiones

Unatareacomnencualquierlenguajedeprogramacineslatoma de decisiones. Un ejemplo de taglibs de toma de decisiones es el siguiente:


1.<g:iftest="${name=='ObiWanKenobi'}"> 2.HelloJedi! 3.</g:if> 4.<g:elseiftest="${name=='Palpatine'}"> 5.HelloSith! 6.</g:elseif> 7.<g:else> 8.Hellounknown! 9.</g:else>

Eltaglibg:ifpermiteevaluarunaexpresinatravsdesuatributo test.LaexpresindebetenerunasentenciaenGroovyquedevuelva un valor booleano. Si la expresin devuelve true, todo el cdigo contenido dentro del taglib es renderizado. En caso contrario, simplementeseomite. Eltaglib g:elseif funcionadelamismaformaque g:if.Sieltaglib

111

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

g:if que lo precede devuelve false, g:elseif es evaluado, en caso contrarionoestomadoencuenta.Esrequisitoqueantesde g:elseif existag:if.Algosimilarocurrecong:else,conladiferenciadequeno existeexpresinaevaluar.Esindispensablequeantesde g:elseexiste ung:ifoung:elseif. Unejemplodelusodeg:ifseencuentraenunfragmentodecdigo en el archivo mencionado con anterioridad, views/profesor/create.gsp:
<g:iftest="${flash.message}">

Existeuntaglibquehacelocontrariode g:if: g:unless.Estetaglib renderizasucontenidosilaexpresincontenidaensuatributo test nosecumple:


1.<g:unlesstest="${name=='Fred'}"> 2.Hello,mynameisnotFred,is${name}! 3.</g:unless>

7.7.2

Iteraciones

Otra de las funciones ms utilizadas en los lenguajes de programacin es el ciclo controlado por contador (for) o centinela (while). Grails permite ejecutar dichos ciclos mediante los taglibs g:eachyg:while,respectivamente. Eltaglibg:eachfuncionacomounciclocontroladoporcontador.En JSPyenGSP,lafuncionalidaddeunciclo forseextiendeparaiterara travsdelistasycoleccionesdeobjetos:
1.<g:eachin="${books}"> 2.<p>Title:${it.title}</p>

112

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
3.<p>Author:${it.author}</p> 4.</g:each> 5.<g:eachvar="book"in="${books}"> 6.<p>Title:${book.title}</p> 7.<p>Author:${book.author}</p> 8.</g:each> 9.<g:eachvar="book"in="${books}"status="i"> 10.<p>Iteration:${i}</p> 11.<p>Title:${book.title}</p> 12.<p>Author:${book.author}</p> 13.</g:each>

El taglib g:each tiene 3 atributos. El atributo in (el nico obligatorio)recibeunaexpresinquerepresentaunavariable.Dicha variable debe ser una lista o un rango en Groovy. El atributo var representa el nombre del item actual en la iteracin. El atributo status lleva el conteo de las iteraciones realizadas, comenzando en cero. Un ejemplo de la utilizacin de views/profesor/list.gsp:
<g:eachin="${profesorInstanceList}"status="i"var="profesorInstance">

g:each

est en

Existeuntaglibespecial,g:eachError,quepermiteiteraratravsde los errores de una instancia de clase de dominio. Este taglib se explicaadetalleenlaseccin7.7.5:
1.<g:eachErrorbean="${book}"> 2.<li>${it}</li> 3.</g:eachError>

Los ciclos controlados por centinela se representan mediante el taglibg:while:


1.<g:whiletest="${i<5}"> 2.<%i++%>

113

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
3.<p>Currenti=${i}</p> 4.</g:while>

Este taglib, al igual que g:if y g:elseif, contiene un atributo que recibelaexpresinaevaluar.Dichotaglibnoesmuyutilizadodebido aquepuedeinvolucrarelusodescriptlets. 7.7.3 ElementosHTML

Grails tiene soporte para todos los elementos GUI estndar utilizadosenHTML.Lassiguientesseccionesdescribencadaunode ellos. 7.7.3.1 Formularios El usodeformularios en pginaswebes una de las tareas ms comunes. El taglib g:form permite crear un form que enva las consultasauncontroladoryaccinespecifica:
1.<g:formname="myForm"action="myaction"id="1"> 2.... 3.</g:form>

EstetaglibgeneraelsiguientecdigoHTML:
1.<formaction="/shop/book/myaction/1"method="post"name="myForm" 2.id="myForm"> 3.... 4.</form>

Generalmente, todos los formularios son enviados al servidor medianteunbotondetipo submit.Eltaglib g:submitButton permite generarunabotndeestetipo:
<g:submitButtonname="update"value="Update"/>

114

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

Este taglib no permite el uso de varios botones dentro de un formulario.Paralograresto,seutilizaeltaglibg:actionSubmit:


<g:actionSubmitvalue="${message(code:'label.update')}"action="Update"/>

Unejemplodelusodeestostaglibsqueejemplificaladiferenciade usoentreambosseencuentraenlosarchivos create.gsp y edit.gsp. En create.gsp, se utiliza g:submitButton para enviar la informacin, mientras que en edit.gsp se debe utilizar g:actionSubmit porque se tienen2acciones:UpdateyDelete: Encreate.gsp:
1.<divclass="buttons"> 2.<spanclass="button"><g:submitButtonname="create"class="save" 3.value="${message(code:'default.button.create.label', 4.default:'Create')}"/> 5.</span> 6.</div>

Enedit.gsp:
1.<divclass="buttons"> 2.<spanclass="button"><g:actionSubmitclass="save"action="update" 3.value="${message(code:'default.button.update.label', 4.default:'Update')}"/> 5.</span> 6.<spanclass="button"><g:actionSubmitclass="delete"action="delete" 7.value="${message(code:'default.button.delete.label', 8.default:'Delete')}" 9.onclick="returnconfirm('${message(code: 10.'default.button.delete.confirm.message', 11.default:'Areyousure?')}');"/> 12.</span> 13.</div>

115

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

7.7.3.2 Camposdetexto Eltaglibg:textFieldgenerauncampodecapturadetexto:


<g:textFieldname="myField"value="${myValue}"/>

El nicoatributorequeridoesname,elatributovalueesopcional. TodosloselementosdefinidosparaelelementoHTML input [W3C01] detipotextpuedenserincluidos:


<g:textFieldname="myField"value="${myValue}"size="40"maxLength="40"/>

Eltaglibg:textAreageneraunreadetexto:
<g:textAreaname="myField"value="myValue"rows="5"cols="40"/>

Losatributosfuncionandelamismaformaqueeltaglib g:textField. Es interesante la forma en que Grails maneja ambos taglibs en la generacindelasvistas.Cuandouncampodetipojava.lang.String tieneensusrestriccionesunalongitudmenoroiguala250,seutiliza g:textField,encasocontrario,seusag:textArea. Paraelusodecamposdetextoqueinvolucrencontraseas,Grails proporcionaeltaglibg:passwordField:
<g:passwordFieldname="myPasswordField"value="${myPassword}"/>

Nuevamente, los atributos funcionan de la misma forma que el taglibg:textField. Elusodecamposocultos(hidden)escomncuandosenecesita manipularunvalorfijoqueesproporcionadoporelservidorperono debesermanipuladoporelusuario.Eltaglib g:hiddenFieldpermiteel usodedichoscampos:
<g:hiddenFieldname="myField"value="myValue"/>

Un ejemplo de uso de este campo se encuentra en

116

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

views/profesor/show.gsp:
<g:hiddenFieldname="id"value="${profesorInstance?.id}"/>

El valor del campo oculto es enviado desde el servidor y es necesarioparaidentificarculregistroesenviadoalaspantallasde edicinyeliminacin. 7.7.3.3 Listasdesplegables Grails facilita el uso de listas desplegables mediante el taglib g:select.Estetaglibrecibeunalistaomapadeelementos,talycomo semuestraacontinuacin:
1.//Generaunalistautilizandounrango 2.<g:selectname="user.age"from="${18..65}"value="${age}" 3.noSelection="['':'Chooseyourage']"/> 4. 5.//GeneraunalistaconunvalornulopredeterminadoparaNoseleccin 6.<g:selectid="type"name='type.id'value="${person?.type?.id}" 7.noSelection="${['null':'SelectOne...']}" 8.from='${PersonType.list()}' 9.optionKey="id"optionValue="name"/> 10. 11.//Generaselectsdetipomltiple 12.<g:selectname="cars"from="${Car.list()}"value="${person?.cars*.id}" 13.optionKey="id" 14.multiple="true"/>

Un ejemplo de uso de g:select est en el archivo GSP views/profesor/create.gsp:


1.<g:selectname="profesor.id" 2.from="${mx.edu.uaeh.promep.Profesor.list()}" 3.optionKey="id"value="${profesorInstance?.profesor?.id}"/>

117

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

La tecnologa de scaffolding utiliza g:select para las asociaciones onetomanyentrelasclasesdedominio. Un uso especial de listas desplegables se da con el taglib g:datePicker.Grailsutiliza estetaglib cuandouna clasede dominio poseeunatributodetipojava.util.Date.SilaclaseProfesortuvieraun atributo llamado fechaNacimiento, se obtendra cdigo similar al siguiente:
1.<g:datePickername="fechaNacimiento"precision="day" 2.value="${profesorInstance?.fechaNacimiento}"/>

Por cada atributo de la fecha (ao, mes, dia, hora y minuto), se generaunalistadesplegable.Unatributointeresantede g:datePicker esprecision.Esteatributopermiteespecificarlaprecisinmximaque el usuario puede manipular.Enelejemplo mostrado, segeneran3 listasdesplegablesparaao,mesyda,respectivamente.Elnmero mximodelistasdesplegableses5. 7.7.3.4 Elementosdeseleccin Eltaglibg:checkBox permiterenderizarunelementoHTMLdetipo checkbox.Normalmenteesutilizadopararepresentarvaloresdetipo booleano:
<g:checkBoxname="myCheckbox"value="${true}"/>

Otros elementos HTML para seleccin bastante comunes son los radioButtton.Grailsposee2taglibsparaelmanejodeellos.Elprimero esg:radio,quegeneraelcdigonecesarioparaunsoloelemento:
1.<g:radioname="myGroup"value="1"/> 2.<g:radioname="myGroup"value="2"checked="true"/>

118

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
3. 4.//ElcdigoHTMLequivalentees: 5.<inputtype="radio"name="myGroup"value="1"/> 6.<inputtype="radio"name="myGroup"checked="checked"value="2"/>

Elsegundotaglibes g:radioGroup,quepermitemanejarunalista de radioButton.Laventajadeestetaglibesque nicamentepermite seleccionarunelementoalavez:


1.<g:radioGroupname="myGroup"values="[1,2,3]"value="1"> 2.<p><g:messagecode="${it.label}"/>:${it.radio}</p> 3.</g:radioGroup> 4.//ElcdigoHTMLequivalentees: 5.<p>Radio1:<inputtype="radio"name="myGroup"value="1" 6.checked="checked"/></p> 7.<p>Radio2:<inputtype="radio"name="myGroup"value="2"/></p> 8.<p>Radio3:<inputtype="radio"name="myGroup"value="3"/></p>

Dentro del cuerpo del taglib g:radioGroup se pueden utilizar 2 variables: it.label e it.radio, las cuales pueden utilizarse para la etiquetadelelementoactualyelelementoens,respectivamente. 7.7.3.5 Cargadearchivos Sidentrodeunaclasededominioseespecificaunatributodetipo byte[],Grailslorenderizaenlasvistascomounarchivoacargar.El taglibutilizadoesg:uploadForm:
1.<g:uploadFormaction="guardaArchivo"> 2.<inputtype="file"name="myFile"/> 3.</g:uploadForm>

En la base de datos, los atributos de tipo byte[] se mapea como campos de tipo BLOB (o su equivalente, dependiendo del gestor utilizado).Sisedeseaguardarelarchivoendiscoenlugardeutilizar

119

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

la base de datos, se debe utilizar una accion similar a la que se muestraenlasiguientepiezadecdigo:


1.defguardaArchivo={ 2.//SeutilizaunobjetoMultipartFiledeSpring 3.defmf=request.getFile('myFile') 4.//Elarchivoaguardarnodebesobrepasarlos200KB 5.if(!mf?.empty&&mf.size<1024*200){ 6.mf.transferTo(newFile("/images/myFile.txt")) 7.} 8.}

7.7.3.6 Vnculosyrecursosestticos Grailspermitelacreacindevnculosenbaseasuscontroladores, accioneseids.Eltaglibg:linkgeneraelementosHTMLdetipoanchor, quesonlabasedelosvnculosenlaWeb:


1.<g:linkaction="show"id="1">Book1</g:link> 2.<g:linkaction="show"id="${currentBook.id}">${currentBook.name}</g:link> 3.<g:linkcontroller="book">BookHome</g:link>

Existeotrotaglib, g:createLink quepermitegenerar nicamentela URL sin necesidad de utilizar el elemento anchor. Este taglib es extremadamente til en la generacin de vnculos en cdigo JavaScript:
1.<g:createLinkaction="show"id="1"/>==/shop/book/show/1 2.<g:createLinkcontroller="book"/>==/shop/book 3.<g:createLinkcontroller="book"action="list"/>==/shop/book/list

Ya que se menciona JavaScript, Grails permite la renderizacin correcta de bloques de cdigo de este lenguaje mediante el taglib g:javascript:

120

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
1.//Llamaalarchivo'/app/js/myscript.js' 2.<g:javascriptsrc="myscript.js"/> 3.//CargatodoslosarchivosjsnecesariosparautilizarScriptaculous 4.<g:javascriptlibrary="scriptaculous"/> 5.<g:javascript>alert('hello')</g:javascript>

Lacargaderecursosestticos(archivosJS,CSS,imgenes,etc)se facilitamedianteeltaglibg:resource:
1.//Genera/shop/css/main.css 2.<g:resourcedir="css"file="main.css"/> 3. 4.//Generahttp://portal.mygreatsite.com/css/main.css 5.<g:resourcedir="css"file="main.css"absolute="true"/> 6. 7.//Generahttp://admin.mygreatsite.com/css/main.css 8.<g:resourcedir="css"file="main.css" 9.base="http://admin.mygreatsite.com"/>

EnlasprimerasversionesdeGrailsseutilizaba g:createLinkTopara lacargaderecursosestticos,peroestetaglibhasidodeclaradocomo obsoletoyserecomiendautilizarg:resourceensulugar. 7.7.4 Tablas

LasvistasgeneradasporGrails,especialmentelosarchivos list.gsp, utilizantablasparadesplegarlosregistrosalmacenadosenlabasede datos.Estastablastienenlapropiedaddepaginaci n,locualfacilita la navegacin de registros. El taglib g:paginate es utilizado para realizar la paginacin de tablas. La siguiente pieza de cdigo pertenecealarchivoviews/profesor/list.gsp
<g:paginatetotal="${profesorInstanceTotal}"/>

eltaglibpuedesereditadoconvariosatributos:

121

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
1.<g:paginatecontroller="profesor"action="list" 2.total="${Profesor.count()}"/>

Acompaandoalapaginacin,lascolumnasdelastablasdeGrails pueden ordenarse de forma ascendente o descendente. El taglib utilizadoparaimplementarlaordenacinesg:sortableColumn:


1.<g:sortableColumnproperty="id" 2.title="${message(code:'profesor.id.label',default:'Id')}"/>

7.7.5

Manejodeerroresenclasesdedominio

Talycomosemencion enlaseccin 4.3,lasclasesdedominio puedentenervalidacindedatos.Sialmomentodecrearunregistro setienenerrores,alusuarioselemuestraunaseriedemensajes.En elarchivoviews/profesor/create.gspseobservaelsiguientecdigo:


1.<g:hasErrorsbean="${profesorInstance}"> 2.<divclass="errors"> 3.<g:renderErrorsbean="${profesorInstance}"as="list"/> 4.</div> 5.</g:hasErrors>

El taglib g:hasErrors verifica si en el bean proporcionado existen errores.Deencontrarse,eltaglibg:renderErrorsproporcionaunalista deloserroresencontradosenlainstanciaprofesorInstance. Otrotaglibquepermitelamanipulaci ndirectadeloserroreses g:eachError:
1.<g:eachErrorbean="${profesorInstance}"> 2.<li>${it}</li> 3.</g:eachError>

Este taglib hace una iteracin a travs de todos los errores encontrados,conladiferenciaqueelobjeto it dentrodelaiteracin

122

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

contieneelerror,loquefacilitasumanipulacin. 7.7.6 Formatodedatos

Algunos de los atributos utilizados en las clase de dominio necesitanpresentarsealusuarioenunaformam samigable.Un ejemplomuycomneselusodevaloresbooleanos.Esevidentequeal usuarionoselepuedemostrarelvalordeunatributocomotrueo false.Grailsproporcionaentaglibg:formatBooleanparaestoscasos:
<g:formatBooleanboolean="${myBoolean}"true="True!"false="False!"/>

Los atributos true y false se utilizan para especificar el texto a mostrarencadacaso,respectivamente. Otro dato muy comn es java.util.Date, cuya representacin por defecto no es muy amigable. El taglib g:formatDate permite dar un formatoadecuadoalasfechas:
<g:formatDateformat="yyyyMMdd"date="${date}"/>

Enelejemplo,el25denoviembrede1980sedespliegacomo 1980 1125.Elatributoformatestabasadoenladocumentacindelaclase java.text.SimpleDateFormat[JAV01]. Existen aplicaciones que requieren presentar cifras y cantidades monetariasenunformatoespecfico.Eltaglibg:formatNumberfacilita estatarea:
1.<g:formatNumbernumber="${myNumber}"format="\\$###,##0"/> 2.<g:formatNumbernumber="${myCurrencyAmount}"type="currency" 3.currencyCode="USD"/>

123

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

7.7.7

Usodevariables

Acontinuacinseexplicanalgunostaglibsqueson tilesparael manejodevariablesenviadasporelcontroladorhacialavista. El taglib g:set crea una variable dentro del GSP de una forma elegante. Dicha variable puede ser utilizada nicamente dentro del archivoGSPdondeseestdeclarando:
1.<g:setvar="counter"value="${1}"/> 2.<g:eachin="${list}"> 3.${counter}.&nbsp;${it}>${counter%2==0?'even':'odd'} 4.<g:setvar="counter"value="${counter+1}"/><br/> 5.</g:each>

Eltaglib g:fieldValue permiteobtenerelvalordelatributodeuna variableoinstanciadeclasededominio.Suprincipalventajaradica enqueelvalordelatributoescodificadoparadesplegarsedeforma apropiadaenlapginaWeb:


1.<p>${book.title}"</p> 2.<p><g:fieldValuebean="${book}"field="title"/></p>

Supnganse que el atributo title tiene un valor <b>Ttulo de la obra</b>.ElprimerejemplorenderizaTtulodelaobraennegrita, y en algunos navegadores el acento suele aparecer de forma incorrecta. El segundo ejemplo, en cambio, utilizar secuencias de escapedeHTMLparamostrarelcontenidocorrectamente. Eltaglibg:findAllutilizaelmtodofindAll delJDKdeGroovypara iteraratravsdeciertoselementosquecumplanconunacondicin:
1.StephenKing'sBooks: 2.<g:findAllin="${books}"expr="it.author=='StephenKing'"> 3.<p>Title:${it.title}</p>

124

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
4.</g:findAll>

Elejemploanterioriteraatravsdetodoslosatributosauthordela variablebookscuyocontenidoseaigualaStephenKing. Eltaglibg:collectfuncionadelamismaformaqueg:findAll,conla diferenciadequenoexisteexpresinbooleanaaevaluar:


1.Bookstitles: 2.<g:collectin="${books}"expr="it.title"> 3.<p>Title:${it}</p> 4.</g:collect>

Eltaglibg:greputilizaelmtodogrepdelJDKdeGroovyyfunciona delamismaformaque g:findAll,conladiferenciadequeseusaun filtroenlugardeunaexpresinydichofiltropuedeserunaclase,una expresinregular,unvalorbooleano,etc.


1.StephenKing'snonfictionBooks: 2.<g:grepin="${books}"filter="NonFictionBooks.class"> 3.<p>Title:${it.title}</p> 4.</g:grep> 5.<g:grepin="${books.title}"filter="~/.*Groovy.*/"> 6.<p>Title:${it}</p> 7.</g:grep>

El taglib g:join utiliza el mtodo join del JDK de Groovy para concatenar la representacin toString de cada elemento de una coleccin,utilizandoundelimitadorentrecadauna:
1.<g:joinin="['Grails','Groovy','Gradle']"delimiter="_"/> 2.//ElresultadoesGrails_Groovy_Gradle

7.8

IncorporandoWeb2.0medianteAjax

La documentacin de Grails define su soporte para Ajax de la

125

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

siguientemanera: AjaxeselacrnimodeAsynchronousJavascriptandXMLy eselmotordetrsdelasRichInternetApplications(RIA's). Estetipodeaplicacionesseadaptanmejoralosframeworks dedesarrollo gildeaplicacionesescritasenlenguajescomo RubyyGroovy.Grailsproporcionasoporteparalacreacinde aplicaciones Ajax a travs de su coleccin de taglibs para estatecnologa Pordefecto,GrailstrabajaconunabibliotecaescritaenJavascript llamada Prototype,yatravsdesuspluginssepuedetenersoporte para otro tipo de herramientas, como Dojo, Yahoo UI, Google Web ToolkityjQuery. La caracterstica principal de Ajax es que la actualizaci n de elementosHTMLserealizadeformaasncrona,esdecir,latareade actualizar no involucra toda la pgina, sino nicamente ciertos elementos de la misma. Esto proporciona un mayor dinamismo e interaccinalaspginasWeb. El primer paso para utilizar los taglibs de Ajax en Grails es importar la biblioteca Javascript necesaria dentro del elemento <head>delarchivoGSP:
1.//ImportacindelabibliotecaPrototype 2.<g:javascriptlibrary="prototype"/> 3.//ImportacindelabibliotecaScriptaculousparaanimaciones 4.<g:javascriptlibrary="scriptaculous"/>

Comosemencionaalprincipiodeestaseccin,elsoporteparaAjax

126

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

en Grails es a travs de taglibs. A continuacin se describen detalladamentecadaunodeellos. 7.8.1 g:remoteLink

Este taglib crea un link que al ser utilizado realiza una llamada remotaalservidor:
1.<g:remoteLinkaction="show"id="1"update="divShow"> 2.ShowBook1 3.</g:remoteLink>

Estogeneraunlinkquealserutilizadoinvocaalaacci n showdel controlador correspondiente. La respuesta de dicha accin se renderiza como contenido del elemento divShow. En Grails, las accionesquesonllamadasporlostaglibsdeAjaxutilizanelm todo renderparadevolvercontenidoHTML:
1.defshow={ 2.render"<p>${Book.get(params['id']}</p>" 3.}

No es una buena prctica combinar el cdigo HTML en el controlador,yaqueseviolaelpatrndearquitecturaMVCutilizadoen Grails.Parasolucionaresto,Grailsproporcionaplantillas(templates) quepermitensepararyreutilizarfragmentosdearchivosGSP.Parael ejemplomostrado,laplantillaestaraenelarchivoubicadoengrails app/views/book/_bookTemplate.gsp,yelcontenidodelarchivosera elsiguiente:
<p>${bookInstance}</p>

Y el cdigo de la accin dentro del controlador se cambia de la

127

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

siguienteforma:
1.defshow={ 2.render(template:"bookTemplate", 3.model:[bookInstance:Book.get(params['id']]) 4.}

De esta forma, la respuesta recibida del servidor es un prrafo HTMLconlarepresentacin toString delainstanciasolicitada.Este contenidoserenderizaenelelementodivShowdelapginaweb. 7.8.2 g:remoteField Lavalidacindedatosentiemporealesunanecesidadquetienen muchas aplicaciones web. Ejemplo de ello son los servidores de correo. Cuando un usuario se registra, normalmente se le pide un nombredeusuario.Laaplicacinverificaqueelnombredeusuario introducidoannoexistaynotificaelresultadodesubsquedasin necesidadderecargartodalapgina.Eltaglib g:remoteField genera uncampodetextoqueenvaunallamadaremotaalservidorcadavez que su contenido se actualiza. En el ejemplo prctico se hace una validacindelISBNdeunlibro:
1.<g:remoteFieldname="isbn"maxlength="13" 2.value="${libroInstance?.isbn}"action="validateIsbn" 3.update="isbnValidationMessage"paramName="isbn"/> 4.<divid="isbnValidationMessage"></div>

Laaccindentrodelcontroladorsedefinedelasiguientemanera:
1.defvalidateIsbn={ 2.if(params.isbn.length()!=13){ 3.render"ElISBNintroducidodebetener13caracteres" 4.}

128

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
5.else{ 6.deflibroInstance=Libro.findByIsbn(params.isbn) 7.if(libroInstance){ 8.render"ElISBNintroducidoyaexiste" 9.} 10.else{ 11.render"ElISBNintroducidoesv\u00E1lido" 12.} 13.} 14.}

Aqui,elmtodo render nohaceunallamadaaunaplantilla,sino queenvaunacadenadecaracteresdeformadirecta.Dichom todo tieneunaversatilidadexcelente,porloqueserecomiendaconsultarla documentacin oficial de Grails para conocer su funcionalidad a fondo. 7.8.3 g:remoteFunction El taglib g:remoteFunction genera el cdigo JavaScript necesario pararealizarunallamadaremotaalservidor.Estetaglibpuedeser utilizadodevariasformas:
1.//Llamadaag:remoteFunctionenelmtodoonchangedelelementoHTML 2.<g:selectfrom="[1,2,3,4,5]"onchange="${ 3.remoteFunction(action:'bookByName',update:[success:'great', 4.failure:'ohno'], 5.options=[asynchronous:false])}"/> 6.//Llamadaag:remoteFunctionjuntoconelusodeuna 7.//bibliotecaJavaScript 8.$('mydiv').onclick=<g:remoteFunctionaction="show"id="1"/>

Nteseelusodeltaglibcomounmtodo.Todoslostaglibspueden utilizarseyaseacomomtodosocomotaglibs.Laformadeutilizarlos

129

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages

depende de la respuesta requerida en el servidor y del orden de renderizacindeloselementos. 7.8.4 g:formRemote Eltaglibg:formRemotepermiteelusodeformulariosconAjax.Los datoscontenidosdentrodelformulariosonserializadosyenviadosde formaremotaalservidor.Unacaractersticade g:formRemoteesquesi elnavegadornosoportaJavaScript,elformulariosetratadeforma normal,esdecir,sinllamadasremotas.
1.<g:formRemotename="myForm"on404="alert('notfound!')" 2.update="updateMe"url="[action:'show']"> 3.Login:<inputname="login"type="text"></input> 4.</g:formRemote> 5.<divid="updateMe">thisdivisupdatedbytheform</div>

Enesteejemploexisteunatributointeresante: on404.Lostaglibs deGrailsparaAjaxsoportanllamadasafuncionesJavaScriptencaso de que la llamada remota al servidor enve un cdigo de error. El dinamismo de Grails permite escribir cualquier cdigo de error deseado(on404,on405,on500,etc). 7.8.5 g:submitToRemote Eltaglib g:submitToRemote tambinpermiteelusodeformularios conAjax.Laprincipaldiferenciaconeltaglib g:formRemoteesquese genera un botn que serializa todos los atributos contenidos en el formulariodondeseencuentraeltaglibyhaceunallamadaremotaal servidor.

130

Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
1.<g:formaction="show"> 2.Login:<inputname="login"type="text"></input> 3.<g:submitToRemoteupdate="updateMe"/> 4.</g:form> 5.<divid="updateMe">thisdivisupdatedbytheform</div>

Este taglib contiene prcticamente las mismas funciones que los taglibsmencionadosanteriormente.

7.9

Resumen

Este captulo ha manejado la capa de presentacin de las aplicaciones web realizadas con Grails. Se ha detallado el funcionamientodeloscontroladoresgeneradosmediantelat cnicade scaffolding,se generaronlasplantillas utilizadaspor Grails para la creacindediversosartefactosyserealiz unanlisisexhaustivode lostaglibsdeGrailsutilizadosenlosarchivosGSP. El conocimento adquirido hasta el momento proporciona los cimientos bsicos para la realizacin gil de aplicaciones web con Grails.EnlatercerapartesetrataeldesarrollodeAPI'stipoRESTy elusodeplugins.

131

Parte4.TpicosavanzadosdeGrails

Parte4

TpicosavanzadosdeGrails

Lostpicostratadosenla Parte3 sirvencomofundamentopara que el lector pueda realizar aplicaciones web completamente funcionales. En esta seccin se presentan 2 de los temas ms avanzadosyutilizadosenlaactualidad:webservicesyreutilizaci n desoftware. EnelCaptulo8:DesarrollodeAPI'stipoRESTconGrails,seexplica la forma en que Grails implementa las 4 operaciones del protocolo HTTP utilizadas en REST (GET, POST, PUT y DELETE) mediante controladores, as como la forma en que los datos son enviados y recibidosmedianteunodelosformatosampliamenteutilizadospara la comunicacin entre 2 aplicaciones distintas: XML (Extensible MarkupLanguage). Para finalizar el estudio de Grails, en el Captulo 9: Plugins, se destaca la aceleracin del desarrollo de software mediante la reutilizacindepiezasyaexistentesysemotivaallectorenelusode labibliotecadecomplementosdeGrails.Semuestralafuncionalidad dealgunosdeestoscomplementoscomoeslaexportacindedatos hacia diversos formatos, ingeniera inversa de bases de datos y la creacindetablasdinmicasmedianteAjaxconJQGrid.

132

Captulo8.DesarrollodeAPI'stipoRESTconGrails

Captulo8

DesarrollodeAPI'stipoRESTconGrails

EldesarrollodeaplicacionesWeb2.0hageneradounanecesidad debido al crecimiento exponencial de la conexin en red de las personas: la comunicacin remota de diversas aplicaciones cuyos lenguajes de programacin e inclusive los dispositivos que las ejecutannosonnecesariamentelosmismos.Escomnconsultarel correoelectrnicotantoenunacomputadoradeescritoriocomoen undispositivo mvil (telfono celular, smartphone,blackberry, etc.); hacrecidoengranmedidaelnmerodeaplicacionestipoclienteque seconectanaTwitteryFacebooksininterferirenlainfraestructura internadeestasredessociales.EldesarrollodeAPI'stipoRESTest tomando mucha fuerza y se est convirtiendo en una de las tecnologasmasutilizadasparalograrlacomunicacinremotaentre clientesyservidores.

8.1

QueesunAPI?

Un API es una interfaz de programacin de aplicaciones (Application Programming Interface, por sus siglas en ingls). Bsicamente es una coleccin de funciones, clases y diversos componentesdeunlenguaje,frameworkoaplicacinquefacilitaalos desarrolladoreslageneracindesoftware. UnadelasprimerasAPI'sfuelaBibliotecaEstndardePlantillas del lenguaje C++. Asimismo, Java posee un conjunto de clases y elementosprobados que puedenusarse para evitar la repeticinde cdigo. Todas las bibliotecas de clases desarrolladas por terceros

133

Captulo8.DesarrollodeAPI'stipoRESTconGrails

mediante Java son consideradas API's. En los ltimos aos, el conceptodeAPIsehaextendidoparaincluirlosserviciostipoREST quelasaplicacioneswebofrecen.

8.2

ArquitecturaREST

REST es el acrnimo de Representational State Transfer (Transferencia de Estado Representacional). De acuerdo a [WIK01], REST afirma que la web ha disfrutado de escalabilidad como resultadodeunaseriedediseosfundamentalesclave: Un protocolo cliente/servidor sin estado. Cada mensaje HTTPcontienetodalainformacinnecesariaparacomprender lapeticin.Comoresultado,nielclientenielservidornecesitan recordarningnestadodelascomunicacionesentremensajes. Sinembargo,enlaprctica,muchasaplicacionesbasadasen HTTP utilizan cookies y otros mecanismos para mantener el estado de la sesin (algunas de estas prcticas, como la reescrituradeURL's,nosonpermitidasporREST) Unconjuntodeoperacionesbiendefinidasqueseaplicana todos los recursos de informacin. HTTP en s define un conjunto pequeo de operaciones, las ms importantes son POST,GET,PUTyDELETE.Confrecuenciaestasoperacionesse equiparan a las operaciones CRUD (seccin 3.8) que se requierenparalapersistenciadedatos,aunquePOSTnoencaja exactamenteenesteesquema. Unasintaxisuniversalparaidentificarlosrecursos. Enun

134

Captulo8.DesarrollodeAPI'stipoRESTconGrails

sistema REST, cada recurso es direccionable nicamente a travsdesuURI. Elusodehipermedios.Larepresentacindeesteestadoenun sistemaRESTsontpicamenteHTMLoXML.Comoresultadode esto,esposiblenavegardeunrecursoRESTamuchosotros, simplementesiguiendoenlacessinrequerirelusoderegistrosu otra infraestructura adicional. Esta caracterstica permite la comunicacin entre diversas aplicaciones que no necesariamente estn escritas en el mismo lenguaje de programacin.

8.3

ImplementacindeunAPItipoREST

El desarrollo de un API tipo REST en Grails es sencillo. Para comenzar,secreauncontroladorllamadoLibroRest:


>grailscreatecontrollermx.edu.uaeh.promep.LibroRest

Comopuedenotarse,sevaagenerarunAPIRESTparaloslibros de los profesores contenidos en el sistema. Una vez generado el controlador,seescribeelsiguientecdigodentrodelmismo:


1.packagemx.edu.uaeh.promep 2. 3.importgrails.converters.XML 4. 5.classLibroRestController{ 6. 7.staticallowedMethods=[list:"GET",show:"GET",create:"POST"] 8. 9.defindex={

135

Captulo8.DesarrollodeAPI'stipoRESTconGrails
10.redirect(action:"list",params:params) 11.} 12. 13.deflist={ 14.params.max=Math.min(params.max?params.int('max'):10,100) 15.renderLibro.list(params)asXML 16.} 17. 18.defshow={ 19.deflibroInstance=Libro.findByIsbn(params.idasString) 20.if(!libroInstance){ 21.deferrorMessage={ 22.error("Libronotfoundwithisbn\"${params.id}\"") 23.} 24.render(contentType:"text/xml;charset=utf8",errorMessage) 25.} 26.else{ 27.renderlibroInstanceasXML 28.} 29.} 30. 31.defcreate={ 32. 33.defxml=request.XML 34.deflibroInstance=newLibro() 35.libroInstance.isbn=xml.isbn.text() 36.libroInstance.titulo=xml.titulo.text() 37.libroInstance.autor=xml.autor.text() 38.libroInstance.edicion=xml.edicion.text()asShort 39.libroInstance.categoria=xml.categoria.text() 40.libroInstance.existenciaTotal= 41.xml.existenciaTotal.text()asInteger 42.libroInstance.cantidadPrestada= 43.xml.cantidadPrestada.text()asInteger

136

Captulo8.DesarrollodeAPI'stipoRESTconGrails
44. 45.defmessage 46.if(libroInstance.save(flush:true)){ 47.message={ 48.status("Librosuccessfullycreated") 49.} 50.} 51.else{ 52.message={ 53.status("Failtocreatelibro") 54.} 55.} 56.render(contentType:"text/xml;charset=utf8",message) 57.} 58. 59.}

Puede notarse la existencia de una lnea de cdigo para la utilizacin de la clase grails.converters.XML (lnea 3). Esta clase es necesaria para enviar una respuesta tipo XML al cliente que haga peticionesalAPI.Lalneadecdigo:
staticallowedMethods=[list:"GET",show:"GET",create:"POST"]

Indica el tipo de mtodo REST a utilizar en cada una de las acciones definidas en el controlador. Para mostrar una lista o un elemento individual, se utiliza el mtodo GET. Para generar nuevos registros, se utiliza el mtodo POST. Si se utiliza otro mtodo, el servidorarrojarunerrorconcdigo405. Dentrodelcontroladorexisten4acciones:index,list,showycreate. Laprimeraredirigealist(seccin7.2.1),lacualcontienelasiguiente lneadecdigo:

137

Captulo8.DesarrollodeAPI'stipoRESTconGrails
renderLibro.list(params)asXML

Se hace uso del mtodo render para enviar una lista en formato XML de libros de acuerdo a los parmetros introducidos (seccin 6.3.2). La Figura 12 muestra la respuesta enviada al navegador al entraraladireccinhttp://localhost:8080/BDPromep/libroRest/.

Figura 12: Respuesta del servidor al invocar la accin list del API REST.

Con una sola lnea de cdigo, Grails ha convertido una lista de objetosenundocumentoXMLquepuedeserutilizadoencualquier

138

Captulo8.DesarrollodeAPI'stipoRESTconGrails

aplicacinparadesplegarinformacinacercadeloslibrosexistentes. Elmtodoshowfuncionadelamismaforma.LaFigura13muestra la respuesta del servidor al buscar el libro con ISBN igual a 1234567890123.

Figura 13: Respuesta del servidor con el mtodo show.

QueocurresiseintroduceunISBNquenoexiste?Lasl neas20a 24 realizan una validacin del ISBN introducido. En caso de no encontrarse un libro con el ISBN enviado, se enva un mensaje de error notificando al cliente que el registro no existe. La Figura 14 muestralarespuestadelservidoralbuscarelISBNisbninvalido.

139

Captulo8.DesarrollodeAPI'stipoRESTconGrails

Figura 14: Respuesta del servidor con el mtodo show con un isbn invlido.

Larespuestaconelmensajedeerrorescreadamedianteunclosure llamado errorMessage.Esteclosureespasadocomounparmetroal mtodorender,asicomoeltipoderespuestaenviada:


deferrorMessage={ error("Libronotfoundwithisbn\"${params.id}\"") } render(contentType:"text/xml;charset=utf8",errorMessage)

Lasacciones list y show puedenutilizarseconunnavegadorweb porque estn especificadas con el mtodo GET. La accin create necesitauntratamientoespecial,yaquesenecesitaenviarunarchivo XML al servidor. Las siguientes secciones hacen uso de una herramientaespecialquepermitehacerpeticionesREST.

8.4

ExperimentandoconelAPI

ElobjetivodelacreacindeunAPIRESTespermitiradiversas

140

Captulo8.DesarrollodeAPI'stipoRESTconGrails

aplicaciones el acceso remoto a diversos recursos de la aplicaci n web.UnaformadeprobarlasaccionestipoGETdelAPIesatrav sde unnavegadorweb.Lasaccionesdeotrotiponecesitanserutilizadas deotraforma. FirefoxpermitelacreacindepeticionesHTTPmediantesuplugin Poster.Medianteestaherramientasepuedeprobarlaaccin create del API recin creada. La Figura 15 muestra la interfaz grfica de PosterparahacerlapeticinPOST.

Figura 15: Plugin Poster para la creacin de peticiones HTTP.

AlpresionarelbotnPOST,seobtienelasiguienterespuestadel servidor.

141

Captulo8.DesarrollodeAPI'stipoRESTconGrails
<status>Librosuccessfullycreated</status>

8.5

SeguridadenAPI'stipoREST

UnadelosaspectosmsimportantesenlaspeticionesHTTPdeun APIRESTeslaseguridad. CuandocomenzaronautilizarselasAPI's tipoREST,noexistanmecanismosdeseguridadquegarantizaranel accesorestringidoarecursosdelservidor.Laautentificacinestndar en HTTP no permita la encriptacin de los datos, por lo que la vulnerabilidaddelservidoreraevidente. Haceunosaoscomenzeldesarrollodeunprotocolodenominado OAuth.EsteprotocolopermiterestringirelaccesoalasAPI'sRESTde los servidores mediante el uso de credenciales enviadas como parmetros ocultos. Al momento de escribir este documento, el desarrollodeOAuthensuversin2.0correacargodeFacebook. Con el paso del tiempo, se espera que el uso de OAuth 2.0 se difundacomounestndarenlaseguridaddeAPI'stipoREST. ParauntratamientodetalladodeOAuth,sesugierevisitar[OAU01].

8.6

Ejemplodelavidareal:elAPIdeTwitter

LasredessocialescomoTwitteryFacebooksehacaracterizadopor permitir a aplicaciones ajenas a su infraestructura el acceso a sus recursos.EnestaseccinsemuestraunejemplodelusodelAPIde Twitter. TwitterofreceladocumentacindesuAPIen [TWI01] (Figura16). Este documento online muestra una lista de las URI's disponibles

142

Captulo8.DesarrollodeAPI'stipoRESTconGrails

parasuuso,asicomolosparmetrosquepuedenrecibir.

Figura 16: Pgina principal del API de Twitter.

TwitterhaceusodeOAuth1.0,porloqueelusodeciertasURI's requieren autentificacin. Para demostrar el uso de la misma, se utilizaunaURLquedevuelveeltimelineentiemporeal.Paraello,se escribe la siguiente direccin web en el navegador: http://api.twitter.com/1/statuses/public_timeline.xml. El API nos enviaunarespuestasimilaralamostradaenlaFigura17.

143

Captulo8.DesarrollodeAPI'stipoRESTconGrails

Figura 17: Respuesta del API de Twitter al solicitar el timeline pblico.

Comoyasehabamencionadoanteriormente,larespuestaenXML permiteacualquieraplicacinhacerusodelainformacinrecibida.

8.7

Resumen

Grails contiene un soporte robusto y estable que permite el desarrollodeAPI'stipoRESTdeformarpidaysencilla.Elcontenido mostrado en este captulo es solo una pequea parte del soporte REST de Grails, por lo que se sugiere consultar la documentaci n oficialparauntratamientomsprofundo. ParaconcluirelestudiodeGrails,elsiguientecaptulohaceusode unadelascapacidadesmspoderosasdeesteframework:elusode plugins.

144

Captulo9.Plugins

Captulo9

Plugins

Unodelosaspectosmsimportantesdelaprogramacinorientada aobjetoseslareutilizacindecdigo.Enmuchasdisciplinassehace uso de la reutilizacin de componentes para evitar la repeticin de cdigo.UnejemplodeelloeslaElectrnica,enlacualsedisponede uncatlogodeelementoselectrnicosqueeldiseadordecircuitos puede utilizar para construir nuevos aparatos, acelerando su desarrolloybasandosutrabajoencomponentesyaexistentes. El mundo del desarrollo de software no es la excepcin. En el Captulo8 semencion queexistenAPI'sdesarrolladasporterceros que pueden ser utilizadas por otros programadores. En el caso de Grails, existe un amplio repositorio de plugins con diversas funcionalidades que aceleran el proceso de desarrollo. En este captulosehaceusodeestasherramientas.

9.1

IntroduccinalospluginsdeGrails

ElrepositoriodepluginsdeGrailscuentaconunaampliavariedad de funcionalidades. Cuando se requiere alguna en especfico, lo primeroquesedebehaceresconsultardichorepositorioparaversi yaexistealgnpluginquecubralosrequerimientos.Lamayorade lasvecesalguienmsyaimplementlasolucinylacomparteconla comunidaddeGrailsmedianteunplugin. Para consultar la lista de plugins disponibles, se ejecuta el siguientecomando:
>grailslistplugins

145

Captulo9.Plugins

Grailscomienzaladescargadelainformacindelosplugins:
Downloading:http://.../pluginslist.xml

Cuando finaliza la descarga, se muestra una lista de los plugins disponibles,delospluginsdisponiblesenGrailsCoreydelosplugins instaladosactualmenteenelproyecto. Parainstalarunplugin,seescribelosiguiente:
>grailsinstallplugin[nombrePlugin]

Parainstalarlaversinespecficadeunplugin,seagregalaversin alcomandoanterior:
>grailsinstallplugin[nombrePlugin][version]

Paradesinstalarunplugin,seejecutalosiguiente:
>grailsuninstallplugin[nombrePlugin]

Lassiguientesseccionesmuestranlainstalaci nyfuncionalidadde algunosplugins.

9.2

Creacindinmicademens

La navegacin estndar de una aplicacin Grails a travs de los diversos catlogos que contiene no es muy amigable. Los vnculos principalesseencuentranenlapginaprincipaldelaaplicacin.Para accederauncatlogo,setienequeescribirlaURLdeformamanualo se tiene que regresar a la pgina principal para obtener el vnculo correspondiente. Grailscuentaconunplugindenominado navigation quefacilitael acceso a los catlogos por medio de un men principal. Para instalarlo,seusaelsiguientecomando:

146

Captulo9.Plugins
>grailsinstallpluginnavigation

Elsiguientepasoesagregarlapropiedadesttica navigation=true enloscontroladores:


1.classProfesorController{ 2.... 3.staticnavigation=true 4.... 5.}

Finalmente,seeditaelarchivo grailsapp/views/layouts/main.gsp paraagregarlassiguientespiezasdecdigo:


1.<html> 2.<head><nav:resources/></head> 3.<body> 4.<divid="menu"> 5.<nav:render/> 6.</div> 7.<g:layoutBody/> 8.</body> 9.</html>

Al ejecutar la aplicacin, se observa un men similar al de la Figura18.

Figura 18: Men generado por el plugin "navigation".

Al hacer clic en alguna de las opciones, el men conduce al catlogocorrespondiente.

147

Captulo9.Plugins

El men puede ser editado de acuerdo a las necesidades del usuario.EjemplodeelloesenelcontroladorProfesorController:


1.staticnavigation=[ 2.group:'tabs', 3.order:1, 4.title:'ListadeProfesores', 5.action:'list' 6.]

Sehaceelmismocambiopara LibroControlleryPrestamoController, cambiandoelatributo order a2y3,respectivamente.Asimismo,se modificaelarchivograilsapp/views/layouts/main.gspdelasiguiente forma:


1.<html> 2.<head><nav:resources/></head> 3.<body> 4.<divid="menu"> 5.<nav:rendergroup="tabs"/> 6.</div> 7.<g:layoutBody/> 8.</body> </html>

Hechosestoscambios,elmenlucecomoenlaFigura19.

Figura 19: Aspecto del men al hacer modificaciones.

Elpluginofreceotrasfuncionalidades,comoelusodesubmensy estilos CSS. Se recomienda consultar [GRA04] para un tratamiento

148

Captulo9.Plugins

detalladodelmismo.

9.3

Exportacindedatosadiversosformatos

Muchasaplicacioneswebutilizantablasparamostrarlosregistros de sus bases de datos. En ocasiones, estas tablas requieren ser trasladadasadiversosformatos,especialmentePDF,hojasdeclculo ytextoplano.ExistenAPI'scomo iText [ITE01] y ApachePOI [APA01] que proporcionan las herramientas necesarias para la generaci n mediantecdigodedichosdocumentos.Grails,porsuparte,ofreceel plugin export,elcualgeneradiversostiposdedocumentosconsolo unclic. Parainstalarlo,seusaelsiguientecomando:
>grailsinstallpluginexport

El siguiente paso es modificar el archivo plugin:

grails

app/conf/Config.groovyparaagregarlosMimeTypessoportadosporel

1.grails.mime.types=[html:['text/html','application/xhtml+xml'], 2.xml:['text/xml','application/xml'], 3.text:'textplain', 4.js:'text/javascript', 5.rss:'application/rss+xml', 6.atom:'application/atom+xml', 7.css:'text/css', 8.csv:'text/csv', 9.pdf:'application/pdf', 10.rtf:'application/rtf', 11.excel:'application/vnd.msexcel', 12.ods:'application/vnd.oasis.opendocument.spreadsheet',

149

Captulo9.Plugins
13.all:'*/*', 14.json:['application/json','text/json'], 15.form:'application/xwwwformurlencoded', 16.multipartForm:'multipart/formdata' 17.]

PosteriormenteseagregaelsiguientetaglibenelheaderdelGSP deseado:
<export:resource/>

Asimismo,seagregalasiguientelneadecdigojustodebajodela paginacindelastablasenlosarchivosgrailsapp/views/../list.gsp:
<export:formatsformats="['csv','excel','ods','pdf','rtf','xml']"/>

Finalmente, se agrega el siguiente cdigo al controlador en el closurelist:


1.packagemx.edu.uaeh.promep 2. 3.importorg.codehaus.groovy.grails.commons.ConfigurationHolder 4. 5.classProfesorController{ 6. 7.defexportService 8.... 9.deflist={ 10.params.max=Math.min(params.max?params.int('max'):10,100) 11.if(params?.format&&params.format!="html"){ 12.response.contentType= 13.ConfigurationHolder.config.grails.mime.types[ 14.params.format] 15.response.setHeader("Contentdisposition", 16."attachment;filename=personas.${params.extension}") 17.exportService.export(params.format,response.outputStream, 18.Profesor.list(params),[:],[:])

150

Captulo9.Plugins
19.} 20. 21.[profesorInstanceList:Profesor.list(params), 22.ProfesorInstanceTotal:Profesor.count()] 23.} 24....

Alejecutarlaaplicacion,seobservaunabarraenlaparteinferior delatablasimilaraladelaFigura20.

Figura 20: Barra de exportacin de datos.

Al hacer clic en alguna de las opciones mostradas, el navegador entregaunarchivoconelformatocorrespondientequecontienelos registros mostrados en la tabla superior. Por defecto,se renderizan todoslosatributosenordenalfabtico.

Figura 21: Reporte generado por el plugin export.

151

Captulo9.Plugins

EnlaaplicacinparaladireccindePROMEPUAEH,serequiere quelosreportesgeneradoscontengantodoslosregistrosdelabasede datosyquepuedanserenviadosaunarchivoPDF,XLSoCSV.La Figura21 muestra unreporteobtenidodela aplicacinenformato PDF. Se aprecia que el documento contiene 52 pginas, lo cual confirmalaentregadetodoslosregistrosexistentes. Las tablas generadas pueden ser estilizadas de acuerdo a las necesidades del usuario. Para un mejor tratamiento del plugin export,sesugiereconsultar[GRA03].

9.4

UsodetablasdinmicasconJQGrid

El uso de JavaScript y Ajax es fundamental para Web 2.0. La presentacinydinamismodeunapginawebhacequesucontenido seainteresanteyllamativo.Grailsfacilitalacreaci ndetablascon jQuery mediante el plugin JQGrid. Para instalarlo, se utiliza el siguientecomando:
>grailsinstallpluginjqgrid

Como ejemplo de uso, se necesita editar el archivo grails app/views/libro/list.gsp sustituyendotodoelcdigoexistenteporel siguiente:
1.<%@pageimport="mx.edu.uaeh.promep.Libro"%> 2.<html> 3.<head> 4.<metaname="layout"content="main"/> 5.<jq:resources/> 6.<jqui:resources/> 7.<jqgrid:resources/>

152

Captulo9.Plugins
8.<scripttype="text/javascript"> 9.$(document).ready(function(){ 10.<jqgrid:grid 11.id="libro" 12.url="'${createLink(action:'listJSON')}'" 13.colNames="'ISBN','Titulo','Autor','Edicion'" 14.colModel="{name:'isbn',editable:false}, 15.{name:'titulo',editable:true}, 16.{name:'autor',editable:true}, 17.{name:'edicion',editable:true}" 18.sortname="'titulo'" 19.caption="'ListadeLibros'" 20.height="300" 21.autowidth="true" 22.scrollOffset="0" 23.viewrecords="true" 24.showPager="true" 25.datatype="'json'"> 26.<jqgrid:filterToolbarid=",libroStandard" 27.searchOnEnter="false"/> 28.<jqgrid:navigationid="libroStandard"add="true" 29.edit="true"del="true"search="true" 30.refresh="true"/> 31.<jqgrid:resizeid="libroStandard" 32.resizeOffset="2"/> 33.</jqgrid:grid> 34.}); 35.</script> 36.</head> 37.<body> 38.<jqgrid:wrapperid="libro"/> 39.</body> 40.</html>

153

Captulo9.Plugins

El cdigo es tomado de la documentacin oficial del plugin [GRA05]. Tambin es necesario agregar la accion listJSON en el controladorcorrespondiente:
1.deflistJSON={ 2.defsortIndex=params.sidx?:'titulo' 3.defsortOrder=params.sord?:'asc' 4.defmaxRows=Integer.valueOf(params.rows) 5.defcurrentPage=Integer.valueOf(params.page)?:1 6.defrowOffset=currentPage==1?0:(currentPage1)*maxRows 7.deflibros=Libro.createCriteria().list(max:maxRows, 8.offset:rowOffset){ 9.if(params.isbn) 10.ilike('isbn',"%${params.isbn}%") 11. 12.if(params.titulo) 13.ilike('titulo',"%${params.titulo}%") 14. 15.if(params.autor) 16.ilike('autor',"%${params.autor}%") 17. 18.if(params.edicion){ 19.ilike('edicion',"%${params.edicion}%") 20.} 21.order(sortIndex,sortOrder).ignoreCase() 22.} 23. 24.deftotalRows=libros.totalCount 25.defnumberOfPages=Math.ceil(totalRows/maxRows) 26. 27.defresults=libros?.collect{ 28.[ 29.cell:[it.isbn,it.titulo,it.autor,it.edicion],

154

Captulo9.Plugins
30. ]

31.} 32. 33.defjsonData=[rows:results,page:currentPage, 34.records:totalRows,total:numberOfPages] 35.renderjsonDataasJSON 36.}

El cdigo tambin es tomado de la documentacin oficial del plugin. Al ejecutar la aplicacin y acceder a la direccin web http://localhost:8080/BDPromep/libro/list,seobtieneunarespuesta similaralamostradaenlaFigura22.

Figura 22: Tabla con JQGrid y Ajax.

ElpluginproporcionaunacodificacinamigabledeJQGrid.Para conocermsadetallesufuncionalidad,sesugierevisitar[JQG01].

9.5

AdicindeSeguridadmedianteSpringSecurity

La seguridad es uno de los aspectos ms importantes de una aplicacinweb.Larestriccindelaccesoadiversosrecursosdeun servidoresunacaractersticaindispensableparaevitarentradasno autorizadas.Springcuentaconunmdulodeseguridaddenominado

155

Captulo9.Plugins

Spring Security, el cual cuenta con una adaptacin para Grails medianteunplugindenominadoSpringSecurityCore. Parainstalarlo,seutilizaelsiguientecomando:
>grailsinstallpluginspringsecuritycore

Elprimerpasoeslacreacinde3clasesdedominio: Clasequerepresentaalosusuarios. Clasequerepresentalosrolesdesempeadosporlosusuarios. Unaclasequerelacionalasdosanteriores.

Paraello,elplugincuentaconuncomando:
>grailss2quickstartmx.edu.uaeh.promepUserRole

Esrecomendableexplorarelcontenidodedichasclases.Unavez creadas, se programa la generacin de 2 usuarios al momento del arranque de la aplicacin a travs del archivo ubicado en grails app/conf/Bootstrap.groovy:
1.importmx.edu.uaeh.promep.Role 2.importmx.edu.uaeh.promep.User 3.importmx.edu.uaeh.promep.UserRole 4. 5.classBootStrap{ 6.defspringSecurityService 7.definit={servletContext> 8.if(User.findByUsername('admin')&& 9.User.findByUsername('user'))return 10.defadminRole=newRole(authority:'ROLE_ADMIN') 11..save(flush:true) 12.defuserRole=newRole(authority:'ROLE_USER') 13..save(flush:true)

156

Captulo9.Plugins
14.Stringpassword= 15.springSecurityService.encodePassword('password') 16.defadminUser=newUser(username:'admin',enabled:true, 17.password:password) 18.adminUser.save(flush:true) 19.defnormalUser=newUser(username:'user',enabled:true, 20.password:password) 21.normalUser.save(flush:true) 22.UserRole.create(adminUser,adminRole,true) 23.UserRole.create(normalUser,userRole,true) 24.assertUser.count()==2 25.assertRole.count()==2 26.assertUserRole.count()==2 27.} 28.}

Finalmente,seagreganlasrestriccionesdeaccesoalasURL'sdela aplicacinenelarchivograilsapp/config/Config.groovy:
1.importgrails.plugins.springsecurity.SecurityConfigType 2.... 3.grails.plugins.springsecurity.securityConfigType= 4.SecurityConfigType.InterceptUrlMap 5.grails.plugins.springsecurity.interceptUrlMap=[ 6.'/profesor/**':['ROLE_ADMIN'], 7.'/grupo/**':['ROLE_ADMIN'], 8.'/plaza/**':['ROLE_ADMIN','ROLE_USER'], 9.'/login/**':['IS_AUTHENTICATED_ANONYMOUSLY'], 10.'/logout/**':['IS_AUTHENTICATED_ANONYMOUSLY'], 11.'/*':['ROLE_ADMIN','ROLE_USER'] 12.]

Al ejecutar la aplicacin, se solicita al usuario introducir sus credenciales(Figura23).

157

Captulo9.Plugins

Figura 23: Solicitud de credenciales con Spring Security.

Se recomienda utilizar los usuarios creados para observar el comportamientodelaaplicacin.Paracerrarsesin,sedebeacceder alaURL http://localhost:8080/BDPromep/logout.Siseiniciasesin como usuario user y se intenta acceder a la lista de personas o libros,seobtieneunmensajedeaccesonoautorizado. ElaccesoalaaplicacinGrailsdeladireccindePROMEPUAEH debe restringirse por medio de claves de usuario y el rol que desempean dentro de la misma direccin. Esto con el fin de especializarlasfuncionesdecadaunodelosusuarios. Enestaaplicacin,seutilizaelplugindeseguridad springsecurity coremencionadoenlaseccin9.5.Lalistadelosdiversosrolesdelos usuarioseslasiguiente: Administrador. Director.

158

Captulo9.Plugins

Trabajador. Recepcionista. Profesor. rea. DES(DependenciasdeEducacinSuperior) CA(CuerpoAcadmico) Directivo.

LapantalladeiniciodesesindelaFigura23semodificaparaser similaralamostradaenlaFigura24.

Figura 24: Pgina de inicio de sesin de la aplicacin Grails de PROMEP-UAEH.

Dependiendo de los roles asignados, se despliega la informacin correspondiente. Por ejemplo, la Figura 25 ilustra el men de un

159

Captulo9.Plugins

usuariotipoDES.

Figura 25: Pantalla principal para un usuario tipo DES.

Como puede observarse, se restringen las funcionalidades del men alasqueelusuariotieneacceso.Estoselogramediantelos taglibsproporcionadosporelplugin. ElpluginparaSpringSecuritydeGrailstienemuchafuncionalidad quepodraabarcarseenunlibrocompleto.Parauntratamientoms profundoacercadelmismo,serecomiendaconsultar[GRA06].

9.6

Ingenierainversadebasesdedatos

Escomnquealhacerunaaplicacinwebyaexistaunabasede datos.Estoocasionaqueeldesarrolladorhagaunmapeomanualde lasclasesdedominioysusrelacionesentresitomandocomobaselas

160

Captulo9.Plugins

tablas existentes. Existe un plugin en Grails llamado db reverse engineeringqueautomatizaestatarea. Tal como se mencionaba en la seccin 2.3.1, la direccin de PROMEPUAEHyacuentaconunabasededatosdondesemanejala informacinpropiadel rea.Paralasnecesidadesmencionadasenel Captulo 2, es necesario retomar la base de datos existente para permitirlaportabilidaddelainformacin. Lainstalacindelpluginserealizadelasiguienteforma:
>grailsinstallplugindbreverseengineer

Posteriormenteseagregalasiguientepropiedadalfinaldelarchivo grailsapp/conf/Config.groovy
grails.plugin.reveng.packageName='mx.edu.uaeh.promep'

Por defecto, el plugin lee todas las tablas y genera las clases correspondientes.Comonosenecesitantodaslastablas,esnecesario indicar las tablas requeridas. Esto se hace agregando la propiedad grails.plugin.reveng.includeTables en el archivo de configuracin grailsapp/conf/Config.groovy:
grails.plugin.reveng.includeTables=['tabla1','tabla2','tabla3']

Finalmente,seejecutaelsiguientecomando:
>grailsdbreverseengineer

Alanalizarlacarpetagrailsapp/domain,sepuedenobservarlas siguientesclasesdedominiogeneradasdeformaautomtica. Unavezqueserealizalaingenierainversaconelcomando grails dbreverseengineer,serevisanlasclasesdedominioparaverificarsi

161

Captulo9.Plugins

sedebenhacer cambiosomodificacionesalcdigogeneradopor el plugin.EnelcasodelaaplicacinparaPROMEPUAEH,esnecesario especificar los nombres de las columnas de los atributos correspondientesobjetosenelclosuremapping(seccin5.4),paraasi manejarapropiadamentelasllavesforneas. Para un tratamiento ms profundo acerca del plugin, se sugiere revisar[GRA07].

9.7

Inclusindeotrospluginsenelsistema

Paraenriquecer laexperiencia delusuarioenlautilizacindela aplicacinGrailsdePROMEPUAEH,seincluyeronpluginsquevan desdeelusodeGUI'sdeJavaScripthastaseguridadenelaccesoala informacin. 9.7.1 UsodecalendariosconelpluginCalendar

Lacapturadefechasendiversosformulariostieneciertosdetalles. Enocasiones,noselesdicealosusuarioselformatodefechaquese requiere,loquepuedeocasionarconfusinymolestias. Grailscuentaconunplugindenominado calendarqueproporciona unainterfazgrficaamigablealusuarioparafacilitarlacapturade fechas. La GUI tiene la forma de un calendario, lo cual facilita al usuariosuusoyfamiliarizacin. LaFigura26muestraelusodecalendar.

162

Captulo9.Plugins

Figura 26: Uso del plugin calendar. 9.7.2 DesplieguedeayudamedianteHelpBallons Enocasiones,losusuariosrequiereninformaci nadicionalacercade lainformacinqueserequierecapturar.Grailscuentaconunplugin llamado helpballoons que permite la inclusin de globos informativos en la aplicacin. La Figura 27 ilustra el uso de este plugin.

163

Captulo9.Plugins

Figura 27: Uso del plugin help-ballons.

9.7.3 GeneracindinmicadegrficasconGoogleCharty jQuery Uno de los objetivos de la aplicacin Grails para la direccin de PROMEPUAEH es la generacin de grficas descriptivas de datos histricosbasadasenlainformacinrecabadaalolargodeltiempo que ayudenen la toma dedecisiones.Para la creacin degrficas, Grails cuenta con un plugin que facilita el uso de la herramienta denominada GoogleChart [GOO01],elcuallleva elmismonombre.

164

Captulo9.Plugins

EstaAPIdetipoREST(Captulo8)recibeunaURLydevuelveuna imagencomorespuesta.LaURLpuedeutilizarseparaserembebida enunapginaweboencualquier aplicacinqueleaimgenespor mediodelprotocoloHTTP. LaFigura28ilustraelusodelplugin googlechartenconjuntocon jQuery paraeldesplieguedeunaventanadedilogoquecontienela grficasolicitada.

Figura 28: Uso de Google Chart y jQuery para la visualizacin de grficas.

Asimismo,laseccindeindicadoresdeltablerodecontrolutilizael pluginparalageneracindediversasgrficas.Estosemuestraenla Figura29.

165

Captulo9.Plugins

Figura 29: Uso de Google Chart para la generacin de grficas de indicadores.

Eltablerodeindicadoresinstitucionalessedivideen6rubros: ProfesoresdeTiempoCompletoconPosgrado. ProfesoresdeTiempoCompletoconDoctorado. ProfesoresdeTiempoCompletoconPerfil. Profesores de Tiempo Completo en el Sistema Nacional de Investigadores. CuerposAcadmicosConsolidados

166

Captulo9.Plugins

CuerposAcadmicosenConsolidacin. ProfesoresdeTiempoCompletoenCuerposAcadmicos.

Larevisinhistricayvisualizacingrficadeestosindicadoresesde granayudaparalatomadedecisionesenladireccindePROMEP UAEH y dems directivos que requieren de esta informacin para fortalecerelprocesodegestinydireccindelaUAEH.

9.8

Resumen

Elusodelrepositoriodepluginsdelframeworkaceleraanms este proceso, proporcionando diversas funcionalidades que otros desarrolladoreshanimplementadoycompartidoconlacomunidadde Grails. Con este captulo se concluye la exploracin de las capacidadesmssobresalientesdeGrailsylaexposicindealgunas desusaplicacionesenelsistemadePROMEPUAEH.

167

Conclusionesyperspectivasafuturo

Conclusionesyperspectivasafuturo
Alolargodeestedocumentosepresent Grails,unaherramienta gildedesarrollodeaplicacioneswebquepermiteentregarresultados en muy poco tiempo. Su facilidad de uso aminora la curva de aprendizajetantoalosdesarrolladoresnovatoscomoexpertos.Astos ltimoslespermiteapreciarlanecesidaddedesarrollardeforma gil (que no es sinnimo de velocidad) mediante la automatizacin de tareasrepetitivasydebajonivel.Asimismo,lespermitereutilizartoda laexperienciaadquiridaeneldesarrollowebconotrosframeworks, comoSpringyHibernate. Lapresentacindeuncasoprcticoimplementadoenladireccin de PROMEPUAEH comprueba que el uso de Grails y sus plugins permite desarrollar funcionalidades que de hacerse con otras herramientas llevaran meses e incluso aos en realizarse, lo que aumenta el valor del uso del framework para entornos cr ticos de entrega. En un futuro, se pretende incluir ms funcionalidad dinmica y asncrona mediante Ajax y la migracin posterior de la aplicacinalaversin2.0deGrails,lacualcontiene,entremuchas otrascaractersticas,lainclusindeHTML5,loquerepresentaun gran paso en la evolucin de los frameworks de desarrollo web. Asimismo, est por liberarse la versin 1.0 de Griffon Framework [GRI01],unaherramientasimilaraGrailsenfocadaalarealizaci nde aplicacionesdeescritoriodesarrolladaymantenidaporelingeniero desoftwaremexicanoAndrsAlmiray.

168

Conclusionesyperspectivasafuturo

Elfuturodeldesarrollodeaplicacionesweb,deescritorioymviles dependerdelaagilidad,creatividadysobretodo,facilidaddeusode los frameworks desarrollados para este fin. Grails y Griffon han marcado la pauta en una nueva generacin de herramientas de desarrolloqueprometenundesarrolloeficiente,sencilloyconfiable. Cabe destacar que las versiones preliminares de este documento hansidorepartidasyaplicadasendiversoscursosyseminarios,entre ellos el Congreso Universitario en Tecnologas de Informacin y Comunicaciones 2011; asimismo, alumnos de octavo semestre han sidointroducidosenelusodeGrailsenlamateriadeBasesdeDatos IIusandoestedocumentocomoreferencia,teniendogranaceptaci n entrelosmismos.

169

Glosariodetrminos

Glosariodetrminos
Ajax:AsynchronousJavaScriptandXML,eslateccnologautilizada parahacerpeticionesasncronasaunservidor,loquepermitemayor dinamismoenlaspginasweb. API: Application Programming Interface, es un conjunto de herramientas de cdigo probadas y optimizadas que pueden ser reutilizadasparalaaceleracindeescrituradecdigo. Bean:EnGrailsySpring,esunaentidaduobjetoquedesempe a unatareadeterminadaeinteractaconotrasparahacerfuncionarel sistema. Bytecodes:EnJava,losbytecodessonelresultadodelacompilacin delcdigofuenteysonellenguajequelaMquinaVirtualdeJava puedeleeryejecutar. Closure:EnGroovy,unclosureesunapiezadecdigosimilaralas clsesannimasdeJavaperoconcapacidadessuperiores. Controlador: En el modelo MVC, el controlador es la parte que conecta a la vista (la interfaz grfica de usuario) con la lgica de negociosdelsistema. DBMS:DataBaseManagementSystem,SistemaGestordeBasesde Datos. DSL (Domain Specific Language): En Groovy, un DSL es una funcinquepermiteextenderellenguajeyfacilitarlafuncionalidad dediversosplugins. Framework: En Ingeniera de Software, un framework es un

170

Glosariodetrminos

conjunto de herramientas cuyo objetivo es facilitar y acelerar el desarrollodecdigomedianteversionesmssencillasdesoftware. GSP:GroovyServerPages,latecnologautilizadaporGrailsparala generacindecdigoHTMLyplantilllasweb. HTML: HyperText Markup Language, Lenguaje de Marcado de Hipertexto;eslatecnologautilizadaporlosnavegadoreswebparala generacinyvisualizacindecontenidoweb. HTTP: HyperText Transfer Protocol, Protocolo de Transferencia de Hipertexto; es el protocolo utilizado para la transmisin de datos entrecomputadoras. JAR: Java Archive, es el formato ms utilizado en Java para almacenarAPI'sycdigoejecutable. JavaScript: Lenguaje Script utilizado en HTML para proporcionar contenidodinmico, JSON: JavaScript Object Notation, es una nomenclatura utilizada paralarepresentacindeobjetosanidadosenJavascript. Mtodos setters y getters: En Java un objeto debe proporcionar acceso a sus propiedades. Esto se logra mediante los m todos get (obtener)yset(establecer). MVC (ModeloVistaControlador): Arquitectura de diseo utilizada parasepararlalgicadenegociosdelainterfazgrficadeusuario, comunicndolasatravsdeuncontrolador. ObjectRelational Mapping: Mapeo ObjetoRelacional, es el paradigmautilizadoparamanipularlasbasesdedatosrelacionales conelparadigmadelaProgramacinOrientadaaObjetos.

171

Glosariodetrminos

Paquete: En Java, un paquete es la ruta en donde se almacenan clasesyrecursosestticos. PDF: Portable Document Format, formato ampliamente utilizado para la generacin de documentos de slo lectura que pueden ser ledosendiversasplataformas Plugin: En Grails, un plugin es un complemento que agrega funcionalidadaunaaplicacinweb. REST: Representational State Transfer, Transferencia de Estado Representacional;tcnicadearquitecturadesoftwareutilizadapara laobtencinygeneracinderecursosenunservidorweb. SCRUM:EnIngenieradeSoftware,SCRUMesunatcnica gilque permite la entrega incremental de software funcional en per odos cortosdetiempo. Sobrecarga de operadores: En programacin, sobrecargar un operador significa proporcionarle mayor funcionalidad. Ejemplo de ello es la sobrecarga del operador +, el cual sirve tanto para la sumadenmeroscomoparalaconcatenacindecadenas SQL: Structured Query Language, Lenguaje de Consultas Estructurado.Ellenguajeestndarparalaconsultaymanipulacin debasesdedatosrelacionales. Taglib:EnJavayGroovy,untaglibesunaetiquetaqueproporciona funcionalidadespropiasamboslenguajesquepuedenserembebidas encdigoHTML. URL: Uniform Resource Locator, conjunto de caracteres que identificanunrecursoenlaweb.

172

Glosariodetrminos

WAR: Web Application Archive, es el formato de Java para el empaquetadodeaplicacionesweb. Wrapper:EnJava,unwrapperesunaclaseenvolventedelosdatos primitivos,detalformaquepuedenserutilizadoscomoobjetos. XML: Extensible Markup Language, formato ampliamente utilizado paralaconfiguracindeaplicacionesyparalatransferenciadedatos enlaweb.

173

Bibliografa

Bibliografa
[AAL01]:AgileAlliance(2011).AgileAlliance.Obtenidoenfebrerode2011 dehttp://www.agilealliance.org/ [APA01]:TheApacheSoftwareFoundation(2011). TheApachePOIProject. Obtenidoenfebrerode2011dehttp://poi.apache.org/ [APT01]: The Apache Software Foundation (2011). Apache Tomcat. Obtenidoenfebrerode2011dehttp://tomcat.apache.org/ [COR07]: Cornejo Velzquez, Eduardo (2007). Sistema de Soporte a las DecisionesOrientadoaWeb.TesisdeMaestra,UniversidadAutnomadel EstadodeHidalgo. [DEI07]: Deitel & Deitel (2007). Java, How to Program. (Edicin 7). EditorialPrenticeHall. [DIN04]:MartinFowler(2004).TheDependencyInjectionpattern.Obtenido enfebrerode2011dehttp://martinfowler.com/articles/injection.html [FLX01]:SpringSource(2011).SpringFlex.Obtenidoenfebrerode2011de http://www.springsource.org/springflex [GLA01]: Oracle (2011). GlassFish Open Source Application Server . Obtenidoenfebrerode2011dehttp://glassfish.java.net/ [GOO01]: Google (2011). Google Chart. Obtenido en febrero de 2011 de http://code.google.com/apis/chart/ [GRA01]: Spring Source (2011). Grails: The search is over. Obtenido en febrerode2011dehttp://grails.org/ [GRA02]:SpringSource(2011).GrailsDocumentation.Obtenidoenfebrero de2011dehttp://grails.org/doc/latest/ [GRA03]:SpringSource(2011).ExportPlugin.Obtenidoenfebrerode2011 dehttp://www.grails.org/plugin/export [GRA04]:SpringSource(2011). NavigationPlugin.Obtenidoenfebrerode 2011dehttp://www.grails.org/Navigation+Plugin

174

Bibliografa

[GRA05]:SpringSource(2011).JQGridPlugin.Obtenidoenfebrerode2011 dehttp://grails.org/plugin/jqgrid [GRA06]:SpringSource(2011).SpringSecurityPlugin.Obtenidoenfebrero de2011dehttp://j.mp/bJ254y [GRA07]: SpringSource (2011). Reverse Engineering Plugin. Obtenido en febrerode2011dehttp://grails.org/plugin/dbreverseengineer [GRA09]:GlenSmith,PeterLedbrook(2009).GrailsinAction.(Edicin1). EditorialManning. [GRI01]:CodehausFoundation(2011). TheGriffonFramework.Obtenido enfebrerode2011dehttp://griffon.codehaus.org/ [GRO01]: Groovy (2011). Groovy A dynamic language for the Java platform.Obtenidoenfebrerode2011dehttp://groovy.codehaus.org/ [HDC01]:JBossCommunity(2011).HibernateDocumentation.Obtenidoen febrerode2011dehttp://www.hibernate.org/docs [HIB01]:JBossCommunity(2011). HibernateRelational Persistencefor Java.Obtenidoenfebrerode2011dehttp://www.hibernate.org/ [HIB02]:JBossCommunity(2011). Restrictionsdocumentation. Obtenido enfebrerode2011dehttp://j.mp/uwUQDY [HIB03]:JBossCommunity(2011). HQL:TheHibernateQueryLanguage. Obtenidoenfebrerode2011dehttp://j.mp/sOYPjL [HSQ01]: HyperSQL (2011). HSQLDB. Obtenido en febrero de 2011 de http://hsqldb.org/ [IAN05]: Ian Somerville (2005). Ingeniera de Software. (Edicin 7). EditorialAddisonWesley. [IEE01]: IEEE (2011). Standard for Binary FloatingPoint Arithmetic. Obtenidoenfebrerode2011dehttp://grouper.ieee.org/groups/754/ [ITE01]: iText (2011). iText. Obtenido en febrero de 2011 de http://www.itextpdf.com/ [JAV01]: Oracle (2011). SimpleDateFormat class. Obtenido en febrero de

175

Bibliografa

2011dehttp://j.mp/upLhzC [JAV02]:Oracle(2011).TheNumbersClasses.Obtenidoenfebrerode2011 dehttp://j.mp/tQtyRG [JAX01]: Oracle (2011). JAXWS Reference Implementation. Obtenido en febrerode2011dehttp://jaxws.java.net/ [JDB01]:Oracle(2011). JDBCOverview.Obtenidoenfebrerode2011de http://j.mp/vSwg1H [JEE10]:EricJendrock,IanEvansyotros(2010).TheJavaEE6Tutorial: BasicConcepts.(Edicin4).EditorialJavaSeries. [JET01]: Codehaus Foundation (2011). Jetty WebServer. Obtenido en febrerode2011dehttp://jetty.codehaus.org/jetty/ [JGO01]:Wikipedia(2011).JamesGosling.Obtenidoenfebrerode2011de http://en.wikipedia.org/wiki/James_Gosling [JMA01]: Oracle (2011). JavaMail. Obtenido en febrero de 2011 de http://j.mp/uDoYIX [JMS01]:Oracle(2011). JavaMessagingService.Obtenidoenfebrerode 2011dehttp://j.mp/rzYfBO [JQG01]: jQuery (2011). JQGrid Documentation. Obtenido en febrero de 2011dehttp://www.trirand.com/blog/ [JSP01]:Oracle(2011).JavaServerPagesTechnology.Obtenidoenfebrero de2011dehttp://j.mp/uR61dU [KAP99]:RobertS.Kaplan,DavidP.Norton(1999). Elcuadrodemando integral.(Edicin3).EditorialGestin2000. [KGP05]: Andrew Davison (2005). Killer Game Programming in Java. (Edicin 1). Editorial O'Reilly. Seccin "Java Is Too Slow for Games Programming". [MSQ01]: Oracle (2011). MySQL. Obtenido en febrero de 2011 de http://www.mysql.com/ [MSS01]:MicrosoftInc.(2011).SQLServer.Obtenidoenfebrerode2011de

176

Bibliografa

http://www.microsoft.com/sqlserver/ [MVC01]:Wikipedia(2011). Modelviewcontroller.Obtenidoenfebrerode 2011dehttp://j.mp/oR1wwT [OAU01]: The OAuth Community (2011). OAuth. Obtenido en febrero de 2011dehttp://oauth.net/ [PRE01]:RogerS.Pressman(2005). IngenieradelSoftware:UnEnfoque Prctico.(Edicin6).EditorialMcGrawHill.Pgina20. [PRE02]:RogerS.Pressman(2005). IngenieradelSoftware:UnEnfoque Prctico.(Edicin6).EditorialMcGrawHill.Pgina92. [PRE03]:RogerS.Pressman(2005). IngenieradelSoftware:UnEnfoque Prctico.(Edicin6).EditorialMcGrawHill.Pgina52. [PRE04]:RogerS.Pressman(2005). IngenieradelSoftware:UnEnfoque Prctico.(Edicin6).EditorialMcGrawHill.Pgina50. [PRE05]:RogerS.Pressman(2005). IngenieradelSoftware:UnEnfoque Prctico.(Edicin6).EditorialMcGrawHill.Pgina95. [PRO01]:SecretaradeEducacinPblica(2011). PROMEP.Obtenidoen febrerode2011dehttp://promep.sep.gob.mx/presentacion.html [PYT01]:SpringSource(2011).SpringPython.Obtenidoenfebrerode2011 dehttp://j.mp/tflxTn [RMI01]:Oracle(2011).RemoteMethodInvocation.Obtenidoenfebrerode 2011dehttp://j.mp/uKBAJx [SCR01]: SCRUM (2011). SCRUM: Training, Assessments, Certifications. Obtenidoenfebrerode2011dehttp://www.scrum.org/ [SDN01]:SpringSource(2011).Spring.NET.Obtenidoenfebrerode2011 dehttp://www.springframework.net/ [SMO02]: Spring Source (2011). Spring Mobile. Obtenido en febrero de 2011dehttp://www.springsource.org/springmobile [SPR01]:SpringSource(2011).SpringFramework.Obtenidoenfebrerode 2011dehttp://www.springsource.com/

177

Bibliografa

[SPR02]: Rod Johnson (2002). Expert OneonOne J2EE Design and Development.(Edicin1).EditorialWrox. [TSS04]: Dion Almaer (2004). The Java EE 6 Tutorial: Basic Concepts. Obtenidoenfebrerode2011dehttp://bit.ly/hBofG9 [TWI01]:Twitter(2011).TwitterAPIDocumentation.Obtenidoenfebrerode 2011dehttps://dev.twitter.com/docs [W3C01]: W3Schools (2011). HTML <input> Tag. Obtenido en febrero de 2011dehttp://www.w3schools.com/TAGS/tag_input.asp [WEB01]: IBM (2011). WebSphere. Obtenido en febrero de 2011 de http://www01.ibm.com/software/websphere/ [WIK01]: Wikipedia (2011). Representational State Transfer. Obtenido en febrerode2011dehttp://j.mp/xmFnv [WIK02]:Wikipedia(2011).TablerodeControl.Obtenidoenfebrerode2011 dehttp://es.wikipedia.org/wiki/Tablero_de_control [WLO01]:Oracle(2011). OracleWebLogicServer.Obtenidoenfebrerode 2011dehttp://j.mp/thbVhH

178

AnexoA:InstalacindeGrails

AnexoA:InstalacindeGrails
Esteanexotieneporobjetivoexplicarelprocedimientopasoapaso delainstalacindeGrails.

Prerrequisitos
AntesdecomenzarautilizarGrails,serequieretenerinstaladoel KitdeDesarrollodeSoftwaredeJava,mejorconocidocomo JavaSDK yestablecerunavariabledeentornollamadaJAVA_HOMEqueapunte a la instalacin del mismo. La versin mnima requerida del SDK dependedelaversindeGrailsautilizar: JavaSDK1.4+paraGrails1.0.xy1.1.x. JavaSDK1.5+paraGrails1.2osuperior.

ElSDKsepuededescargarenhttp://j.mp/cyvkd3.

Listadepasosaseguir
DescargarlaltimaversindeGrails. Extraer los archivos en una ruta apropiada, tpicamente C:\grailsenWindowso~/grailsenUnix. Crear una variable de entorno llamada GRAILS_HOME que apuntealarutadondeseextrajoelarchivoZIPdeGrails. Si no se ha creado la variable de entorno JAVA_HOME, es momento de hacerlo. Esta variable debe apuntar a la ruta dondeseencuentrainstaladoelSDKdeJava.

179

AnexoA:InstalacindeGrails

Anexarunareferenciaalacarpetabinubicadadentrodela instalacin de Grails a la variable PATH ( %GRAILS_HOME %\bin en Windows o $GRAILS_HOME/bin en Unix). En entornod Windows, es importante que la variable PATH y la variable GRAILS_HOME estn en el mismo nivel, por ejemplo VariablesdeSistema.

Abrirlalneadecomandosyescribirelcomandograilspara comprobarquelainstalacinhasidoexitosa.

EnsistemasUnix,siseobtieneunmensajedeerror,ejecutarel comandochmod+xgrailsdentrodelacarpetabin.

180

AnexoB:DiagramadeEntidadesdelSistema(CSI)dePROMEPUAEH

AnexoB:DiagramadeEntidadesdelSistema (CSI)dePROMEPUAEH

181

Вам также может понравиться