Creación de plugins con Grails
Upcoming SlideShare
Loading in...5
×
 

Creación de plugins con Grails

on

  • 1,018 views

La presentación que realice para el SpringIO 2012 en Madrid, España...

La presentación que realice para el SpringIO 2012 en Madrid, España
Hablando acerca de la arquitectura de los plugins de Grails y para dar los conocimientos básicos de comprensión del funcionamiento y estructura de componentes que co

Statistics

Views

Total Views
1,018
Views on SlideShare
1,018
Embed Views
0

Actions

Likes
2
Downloads
12
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Creación de plugins con Grails Creación de plugins con Grails Presentation Transcript

  • Creación de plugins con Grails José Juan Reyes Zuñiga(@neodevelop)
  • Agendatalk = new Talk()talk.agenda{ quienSoy() porQueCrearPlugins() arquitecturaDePlugins() estructuraDePlugins() puntosClave()}
  • ¿Quién soy?• 12 años desarrollando software• Varias plataformas y paradigmas• Co-editor y ex-podcaster de SpringHispano.org• Co-fundador y ex-podcaster de la comunidad GrailsMX• Editor de Artesanos.de/software y Scala-Mug.org• Fundador y podcaster de ViveCodigo• Apasionado de Groovy / Grails• Actualmente trabajo en SynergyJ.com View slide
  • ¿Por qué crear plugins?• Clásico: • Modularidad • Proveer funcionalidades muy puntuales • Integrar librerías• Pero... • El plugin hace lo que necesito, sin embargo... • ¿Has tenido problemas al integrar algún(os) plugin(s)? • ¿Lo has resuelto? • ¿Que implica ser el autor de un plugin? View slide
  • Arquitectura de plugins
  • Estructura de un plugin
  • Estructura de un plugin// DOMAIN CLASSES // CONTROLLERSpackage com.synergyj package com.synergyj// Create tables in ypur app // Warning: UrlMappings maybe mapped this in your appclass UberClass { class UberController { String name def create = { /*...Magic...*/ } // More properties... def anotherAction = { /*..More magic..*/ } // A lot of fields and relations // more actions } static constraints = { name(blank:false,unique:true) } // TAGLIBs} // URL MAPPINGS// TAGLIBs // VIEWSpackage com.synergyj // LAYOUTSclass UberTagLib { // UTILS static namespace = "uber" // SCRIPTS def inlineAction = { attrs, body -> // SERVICES // Inline functionality(abuse?) out << body() // src/java } // src/groovy}
  • Cuidado con la flexibilidad...// In your appclass YourClass extends UberClass{ // <--- mmmm, I dont think so} <g:resource dir="${pluginContextPath}/js" file="uber.js" /> <g:render template="viewFolder/templateName" plugin="uber"/> def dependsOn = [:] // Be careful def pluginExcludes = [ "grails-app/views/error.gsp" ]
  • ActiveMQYour App Mail plugin // Relative or absolute grails.plugin.location.uber = "../uber"Your plugin
  • Trabajando con pluginsdef doWithWebDescriptor = { xml -> // Modify the web descriptor at your convenience}def doWithSpring = { // Define and configure beans}def doWithDynamicMethods = { ctx -> // Add behavior to your artifacts}def doWithApplicationContext = { applicationContext -> // Spring is up? Yes, then...}def onChange = { event -> // Learn the magic, because happens some of it in here}def onConfigChange = { event -> // Magic for configuration}
  • Metaprogramación
  • Seek and ... create... application.controllerClasses.each{ cClass -> // Exploring controllers application.isControllerClass(cClass.clazz) // True or false application.getControllerClass(cClass.clazz) // Controller } application.<artifact>Classes.each{ aClass -> application.is<Artifact>Class(aClass.clazz) // True or false application.get<Artifact>Class(aClass.clazz) // Controller } // Properties of artifacts cClass.clazz // The class cClass.metaClass // cClass.clazz.metaClass cClass.name // name without suffix and without packages
  • Seek and ... create... application.domainClasses.each{ dClass -> if(UberInterface.class.isAssignableFrom(dClass.clazz)){ println "The class " + dClass.clazz + " implements UberInterface" dClass.clazz.metaClass { static{ sayHiStatic{ String nombre -> "Hi static $nombre !!!" } } sayHi { String nombre -> "Hi $nombre !!!" } } } } import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU//...def isConfigurable = GCU.getStaticPropertyValue(cClass.clazz, "isConfigurable")if(isConfigurable){ println "Hell Yeah!!!" // Stuff with values from properties in artifacts}//...
  • Class reloading...def observe = ["controllers"]def observe = ["controllers","services","filters","urlMappings","hibernate","i18n"]def onChange = { event -> // event.source // class com.synergyj.MyAppController // event.application // org.codehaus.groovy.grails.commons.DefaultGrailsApplication // event.ctx // org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext // event.manager // org.codehaus.groovy.grails.plugins.DefaultGrailsPluginManager // event.plugin // org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin}
  • Testing...class UberControllerTests extends ControllerUnitTestCase { def uberService protected void setUp() { super.setUp() mockConfig( grails{ plugins{ yourPlugin{ apiKey = YOUR_API_KEY } } } ) } protected void setUp() { void testSomething() { super.setUp() } SpringSecurityUtils.metaClass.static.getSecurityConfig = {} [successHandler: [defaultTargetUrl: "http://localhost:8080/app"]] } }
  • Resumen...• Ubica en un mismo directorio tus plugins y haz referencias relativas• No hagas dependencias fuertes entre tus plugins y tus apps• Trabaja con la metaprogramación, es divertido...(Usa la GroovyConsole)• Explora tus clases(Introspección)• No siempre tienes que manejar los cambios en los artefactos de tu aplicación
  • Gracias!Q &A