Creación de plugins con Grails

  • 699 views
Uploaded on

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
699
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
12
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Transcript

  • 1. Creación de plugins con Grails José Juan Reyes Zuñiga(@neodevelop)
  • 2. Agendatalk = new Talk()talk.agenda{ quienSoy() porQueCrearPlugins() arquitecturaDePlugins() estructuraDePlugins() puntosClave()}
  • 3. ¿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
  • 4. ¿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?
  • 5. Arquitectura de plugins
  • 6. Estructura de un plugin
  • 7. 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}
  • 8. 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" ]
  • 9. ActiveMQYour App Mail plugin // Relative or absolute grails.plugin.location.uber = "../uber"Your plugin
  • 10. 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}
  • 11. Metaprogramación
  • 12. 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
  • 13. 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}//...
  • 14. 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}
  • 15. 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"]] } }
  • 16. 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
  • 17. Gracias!Q &A