Академический Документы
Профессиональный Документы
Культура Документы
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
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
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
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
1.5
ObjetivosEspecficos
DescribirlosfundamentosdeGrailsmedianteelanlisisdela estructuradelosproyectosyloscomponentesdelosmismos para la implementacin gil de aplicaciones web robustas y portables.
ImplementarAPI'stipoRESTparalaexposicinyaccesoremoto dedatos.
Captulo1.Introduccinaldocumento
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
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.
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.
14
Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)
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
16
Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)
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.
2.3
Anlisis
20
Captulo2.Requerimientos,anlisisydiseodelSistemadeControlySeguimientode IndicadoresPROMEPUAEH(CSI)
Modeladodeentidades:consisteenlaidentificacindeobjetos del mundo real involucrados en los procesos descritos en los requerimientosparasurepresentacincomputacional.
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)
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
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?
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?
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
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/domain:enestacarpetaseencuentranlasclasesde dominio.
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
Para visualizar la aplicacin, se debe abrir un navegador web y dirigirse a la direccin http://localhost:8080/BDPromep. El navegador muestralapginadelaFigura6.
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}
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
45
Captulo4.Creacinyarranquedelsistema
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
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
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.
49
Captulo4.Creacinyarranquedelsistema
Alhacerclicenelvnculo,laaplicacinsedirigehacialapantalla principaldelcatlogodeProfesores,comosemuestraenlaFigura8.
50
Captulo4.Creacinyarranquedelsistema
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
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
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'
57
Captulo4.Creacinyarranquedelsistema
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)
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
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
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
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
-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
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.
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
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
69
Captulo5.Dominiodeunaaplicacinweb
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 }
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
70
Captulo5.Dominiodeunaaplicacinweb
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.
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
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
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;
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
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.}
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
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.}
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()
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>
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)
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.
87
Captulo6.ModeloObjetoRelacionalenGrails(GORM)
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.
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
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
Laejecucindeestoscomandosgeneranlossiguientesarchivos(se omitenlosarchivosdeprueba):
BDPromep/ |grailsapp `controllers `mx/edu/uaeh/promep |ProfesorController.groovy |GrupoController.groovy `PlazaController.groovy
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
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">
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
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
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
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
109
Captulo7.CapadepresentacinWeb:ControladoresyGroovyServerPages
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
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}">
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>
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
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
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"/>
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"/>
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"/>
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
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"/>
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()}"/>
7.7.5
Manejodeerroresenclasesdedominio
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
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}. ${it}>${counter%2==0?'even':'odd'} 4.<g:setvar="counter"value="${counter+1}"/><br/> 5.</g:each>
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>
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
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
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>
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
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.
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.
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.
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.
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
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]
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
147
Captulo9.Plugins
Hechosestoscambios,elmenlucecomoenlaFigura19.
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
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']"/>
150
Captulo9.Plugins
19.} 20. 21.[profesorInstanceList:Profesor.list(params), 22.ProfesorInstanceTotal:Profesor.count()] 23.} 24....
Alejecutarlaaplicacion,seobservaunabarraenlaparteinferior delatablasimilaraladelaFigura20.
Al hacer clic en alguna de las opciones mostradas, el navegador entregaunarchivoconelformatocorrespondientequecontienelos registros mostrados en la tabla superior. Por defecto,se renderizan todoslosatributosenordenalfabtico.
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. ]
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.
ElpluginproporcionaunacodificacinamigabledeJQGrid.Para conocermsadetallesufuncionalidad,sesugierevisitar[JQG01].
9.5
AdicindeSeguridadmedianteSpringSecurity
155
Captulo9.Plugins
Spring Security, el cual cuenta con una adaptacin para Grails medianteunplugindenominadoSpringSecurityCore. Parainstalarlo,seutilizaelsiguientecomando:
>grailsinstallpluginspringsecuritycore
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.]
157
Captulo9.Plugins
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
LapantalladeiniciodesesindelaFigura23semodificaparaser similaralamostradaenlaFigura24.
Dependiendo de los roles asignados, se despliega la informacin correspondiente. Por ejemplo, la Figura 25 ilustra el men de un
159
Captulo9.Plugins
usuariotipoDES.
Como puede observarse, se restringen las funcionalidades del men alasqueelusuariotieneacceso.Estoselogramediantelos taglibsproporcionadosporelplugin. ElpluginparaSpringSecuritydeGrailstienemuchafuncionalidad quepodraabarcarseenunlibrocompleto.Parauntratamientoms profundoacercadelmismo,serecomiendaconsultar[GRA06].
9.6
Ingenierainversadebasesdedatos
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
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
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
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.
165
Captulo9.Plugins
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