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

Like this? Share it with your network

Share

Creación de plugins con Grails

  • 1,062 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
1,062
On Slideshare
1,062
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