Grails Plugin

1,321 views

Published on

  • Be the first to comment

Grails Plugin

  1. 1. Introducing of Grails plugin<br />QIYI AD Team<br />Yan Lei<br />
  2. 2. Plug-in Architecture<br />
  3. 3. Plug-in Structure<br />+ grails-app<br /> + controllers<br /> + domain<br /> + taglib<br />etc.<br />+ lib<br />+ src<br /> + java<br /> + groovy<br />+ web-app<br /> + js<br /> + css<br />Just like a normal grails application<br />The only difference is the presence of a file *GrailsPlugin.groovy<br />The content of the grails-app directory will not be copied into main source tree.<br />Code in src and lib directory will be compiled into main app’s web-app/WEB-INF/classes<br />
  4. 4. Creating Plugin<br />grails create-plugin [PLUGIN NAME]<br />Plugin descriptor<br />example from Quartz Grails plugin<br />class QuartzGrailsPlugin { <br />defversion = "0.1" <br />defgrailsVersion = "1.1 > *" <br />defauthor = "Sergey Nebolsin" <br />defauthorEmail = "nebolsin@gmail.com" <br />deftitle = "This plugin adds Quartz job scheduling features to Grails application." <br />defdescription = ''' … ''' <br />… <br />}<br />
  5. 5. Overview of Plugin Closures<br />A plugin can specify multiple closures each of which can manipulate Grails:<br />doWithSpring – Participate in Spring configuration<br />doWithApplicationContext – Post ApplicationContxtinitialisation activities<br />doWithWebDescriptor – Modify the XML generated for web.xml at runtime<br />doWithDynamicMethods – Add methods<br />Some Examples<br />
  6. 6. Hooking into Spring Configuration<br />import org.springframework.web.servlet.i18n.CookieLocaleResolver; <br />import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; <br />import org.springframework.context.support.ReloadableResourceBundleMessageSource;<br />class I18nGrailsPlugin {<br />def version = 0.1<br />def doWithSpring = { <br />messageSource(ReloadableResourceBundleMessageSource) { <br />basename = "WEB-INF/grails-app/i18n/messages" <br />} <br />localeChangeInterceptor(LocaleChangeInterceptor) { <br />paramName = "lang" }<br />localeResolver(CookieLocaleResolver) <br />} <br />}<br />This plugin sets up the Grails messageSource bean and a couple of other beans to manage Locale resolution and switching. It using the Spring Bean Builder syntax to do so.<br />
  7. 7. Hooking into web.xml Generation<br />defdoWithWebDescriptor = { webXml -> <br />defmappingElement = webXml.'servlet-mapping' <br />deflastMapping = mappingElement[mappingElement.size()-1] lastMapping + {<br />'servlet-mapping' { <br />'servlet-name'("grails") <br />'url-pattern'("*.dispatch") <br />} <br />} <br />}<br />Here the plugin goes through gets a reference to the last <servlet-mapping> element and appends Grails' servlet to the end of it using XmlSlurper's ability to programmatically modify XML using closures and blocks.<br />
  8. 8. Doing Post Initialization Configuration<br />defdoWithApplicationContext = { appCtx-> <br />SessionFactorysf = appCtx.getBean("sessionFactory") <br />// do something here with session factory <br />} <br />Sometimes it is useful to be able do some runtime configuration after the Spring ApplicationContext has been built. In this case you can define a doWithApplicationContext closure property.<br />
  9. 9. Adding Dynamic Methods<br />defdoWithDynamicMethods = { applicationContext-><br />String.metaClass.swapCase= {-> <br />defsb = new StringBuffer() <br />delegate.each{ <br />sb<< (Character.isUpperCase(it as char) ? <br />Character.toLowerCase(it as char) : <br />Character.toUpperCase(it as char)) <br />} <br />sb.toString() }<br />assert "UpAndDown" == "uPaNDdOWN".swapCase() <br />} <br />In this example we add a new method swapCase to java.lang.String directly by accessing its metaClass.<br />
  10. 10. Reload Events<br />Grails applications must be reloadable during development<br />Plug-ins can define watchedResources that fire onChange event when modified<br />
  11. 11. Example Reloading Plug-in<br />Class I18nGrailsPlugin{<br />defwatchedResources = <br /> “file:../grails-app/i18n/*.properties”<br />defonChange = { event -><br />defmessageSource = <br />event.ctx.getBean(“messageSource”)<br />messageSource?.clearCache()<br />}<br />}<br />When one changes,event is fired and plugin responds by clearing message cache<br />
  12. 12. The Event Object<br />event.source - The source of the event which is either the reloaded class or a Spring Resource<br />event.ctx- The Spring ApplicationContext instance<br />event.plugin - The plugin object that manages the resource (Usually this)<br />event.application - The GrailsApplication instance<br />
  13. 13. Plugin Load Order<br />Plugin dependencies<br />defdependsOn = [foo: “ * > 1.0”,<br /> bar : “ 1.0 > 1.2”]<br />Load Order<br />defloadAfter = [‘controllers’]<br />
  14. 14. Installing & Distributing<br />grails package-plugin<br />Excluded artefacts when Distributing<br />grails-app/conf/DataSource.groovy<br />grails-app/conf/UrlMappings.groovy<br />build.xml<br />Everything within /web-app/WEB-INF<br />grails install-plugin [name] [file path] [url]<br />Specifying plugin location in ‘BuildConfig.groovy’<br />//useful for modular app where app & plugin in the same directory<br />Grails.plugin.location.’grails-ui’ = “../grails-grails-ui”<br />

×