Download - Grails plugin development
![Page 1: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/1.jpg)
Grails Plugin Development
- Mohd Farid
![Page 2: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/2.jpg)
Agenda
1. What is a plugin
2. Creating and Installing Plugins
3. Understanding a Plugin's Structure
4. Providing Basic Artefacts
5. Accessing the Application’s artefact classes
6. Hooking into Runtime Configuration
7. Adding Dynamic Methods at Runtime
8. Participating in Auto Reload Events
9. Understanding Plugin Load Order
10.Adding our own Artefact Types
11.Releasing our Plugin
![Page 3: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/3.jpg)
What is a plugin
Wikipedia says:
In computing, a plugin is a software component that adds a specific feature to an existing software application.
![Page 4: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/4.jpg)
● Very similar to a Grails application project
● Plus a *GrailsPlugin.groovy plugin descriptor file
● Use grails create plugin to create one
● Often adds artifacts, resources, scripts
● Good for code reuse
● Modular development
What is a Grails plugin
![Page 5: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/5.jpg)
Creating and Installing Plugins
![Page 6: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/6.jpg)
Creating and Installing Plugins
Command grails create-plugin my-first-plugin
Plugin descriptor file
A Groovy file whose name ends with GrailsPlugin
![Page 7: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/7.jpg)
Creating and Installing Plugins contd...
Plugin descriptor specifies the details about the plugin:|
1. title
2. version Example "0.1", "0.2-SNAPSHOT", "1.1.4" etc.
3. grailsVersion - eg. "1.2 > *" (indicating 1.2 or higher)
4. author -
5. authorEmail -
6. description -
7. documentation - URL of the plugin's documentation
![Page 8: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/8.jpg)
Creating and Installing Plugins contd...
Specifying the plugin location:
// Useful to test plugins you are developing.
grails.plugin.location.shiro = "/home/dilbert/dev/plugins/grails-shiro"
// Useful for modular applications where all plugins and
// applications are in the same directory.
grails.plugin.location.'grails-ui' = "../grails-grails-ui"
![Page 9: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/9.jpg)
Demo
Creating an inplace plugin and
configuring it in Application
![Page 10: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/10.jpg)
Understanding a plugin’s structure
![Page 11: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/11.jpg)
Understanding a Plugin's Structure
1. Structure is similar to a normal grails application
2. When installed it differs slightly3. Contents of grails-app will go
into the plugins directory within the host application : plugins/example-1.0/grails-app
4. Not copied into the main source tree.
5. No interfering with the primary application.
6. Java / Groovy/ lib: Goes into web-app/WEB-INF/classes
![Page 12: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/12.jpg)
Providing Basic Artefacts
![Page 13: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/13.jpg)
Providing Basic Artefacts
Adding a new Script:
Add a gant script in scripts folder of the Plugin.
Adding a grails artefact:
Add a new domain, services, controller in the plugin’s respective directories.
![Page 14: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/14.jpg)
Providing Basic Artefacts...Grails' view resolution mechanism
Just like controllers, we can provide default views from the plugin.
Scope to override the views provided by a plugin.
First checks for the view in the application.
If that fails will attempt to look for the view within the plugin.
![Page 15: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/15.jpg)
DemoOverriding plugin view through application
![Page 16: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/16.jpg)
Providing Basic Artefacts...
Files that are not packaged with the plugin:
1. BootStrap.groovy
2. BuildConfig.groovy
3. Config.groovy
4. DataSource.groovy (and any other *DataSource.groovy)
5. UrlMappings.groovy
6. resources.groovy
7. Everything within /web-app/WEB-INF
8. Everything within /web-app/plugins/**
9. Everything within /test/**
10.SCM management files within **/.svn/** and **/CVS/**
![Page 17: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/17.jpg)
Accessing the Application’s artefact classes
![Page 18: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/18.jpg)
Accessing the Application’s artefact classes
GrailsApplication application
1. application an implicit variable (instance GrailsApplication interface)
2. Has methods for accessing all artifact classes within our application.
![Page 19: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/19.jpg)
Accessing the Application ..
Accessing all the Artefact Classes in Application
for (grailsClass in application.allClasses) {
println grailsClass.name
}Accessing all the controller classes:
for (controllerClass in application.controllerClasses){ println controllerClass.name}
![Page 20: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/20.jpg)
Accessing the Application .. Some useful methods and their conventions
1. *Classes - eg application.controllerClasses)
2. get*Class - eg application.getControllerClass("PersonController")
3. is*Class - eg: application.isControllerClass(PersonController)
Artefact names:
4. domain
5. controller
6. tagLib
7. service
8. codec
9. bootstrap
10.urlMappings
![Page 21: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/21.jpg)
Accessing the Application .. Some examples:
● application.domainClasses
● application.controllerClasses
● application.getDomainClass(“Person”)
● application.getControllerClass("PersonController")
● application.isTagLibClass(“ApplicationTagLib”)
![Page 22: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/22.jpg)
Accessing the Application .. Each Artefact implements the GrailsClass :
getPropertyValue - Gets the initial value of the given property on the class
hasProperty - Returns true if the class has the specified property
newInstance - Creates a new instance of this class.
getName - Returns the logical name of the class in the application without the trailing convention part if applicable
getShortName - Returns the short name of the class without package prefix
![Page 23: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/23.jpg)
Accessing the Application ..
some more methods in GrailsClass…
getFullName - Returns the full name of the class in the application with the trailing convention part and with the package name
getPropertyName - Returns the name of the class as a property name
getLogicalPropertyName - Returns the logical property name of the class in the application without the trailing convention part if applicable
getNaturalName - Returns the name of the property in natural terms (eg. 'lastName' becomes 'Last Name')
getPackageName - Returns the package name
![Page 24: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/24.jpg)
DemoAccessing the Artefacts
![Page 25: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/25.jpg)
Hooking into Runtime Configuration
![Page 26: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/26.jpg)
Hooking into Runtime Configuration
1. Hooking into the Grails Spring configuration (doWithSpring)
2. Participating in web.xml Generation (doWithWebDescriptor)
3. Doing Post Initialisation Configuration (doWithApplicationContext)
![Page 27: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/27.jpg)
Adding Dynamic Methods at Runtime
![Page 28: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/28.jpg)
Adding Dynamic Methods at Runtime
def doWithDynamicMethods = { applicationContext -> for (controllerClass in application.controllerClasses) { controllerClass.metaClass.myNewMethod = {-> println "hello world" } } }
![Page 29: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/29.jpg)
Demo
Adding a method through meta-programming
![Page 30: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/30.jpg)
Participating in Auto Reload Events
![Page 31: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/31.jpg)
Participating in Auto Reload Events
Monitoring Resources for Changes
def watchedResources = [ list of files that we want to watch for change]
def onchange = { event->
}
For other plugins
def influences = ['controllers']
def observe = ["controllers"]
![Page 32: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/32.jpg)
Participating in Auto Reload Events
Monitoring Resources for Changes
def watchedResources
Eg values: ["file:./grails-app/jobs/**/*Job.groovy",
"file:./plugins/*/grails-app/jobs/**/*Job.groovy" ]
(from quartz plugin)
def onchange = { event->
println “Changed source: ${event.source}”
//we might want to re inject the meta class methods to certain artefacts.
}
![Page 33: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/33.jpg)
Participating in Auto Reload Events
Monitoring Resources for Changes
event Object
● event.source - The source of the event, either the reloaded Class or a Spring Resource
● event.ctx - The Spring ApplicationContext instance
● event.plugin - The plugin object that manages the resource (usually this)
● event.application - The GrailsApplication instance
● event.manager - The GrailsPluginManager instance
def influences = ['controllers'] // reload the controller plugin when there is any change in my plugin
observes = ["controllers"] // reload my plugin if controller plugin has changes.
![Page 34: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/34.jpg)
Participating in Auto Reload Events
Use Cases:
watchedResources: Quartz Plugin watches for changes Job Artefact.
influences: Service plugin influences controllers.
observes: Mail plugin wants to be notified if services or controller plugin has
changes.
![Page 35: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/35.jpg)
Demo Watched Resources & OnChange events
![Page 36: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/36.jpg)
Understanding Plugin Load Order
![Page 37: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/37.jpg)
Understanding Plugin Load Order
Hard dependency def dependsOn = [foo: "* > 1.0"]def dependsOn = [foo: "1.0 > 1.1"]def dependsOn = [foo: "1.0 > *"]
Weaker dependencydef loadAfter = ['controllers']def loadBefore = ['controllers']
![Page 38: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/38.jpg)
Understanding Plugin Load Order
Interacting with other plugins
manager: another implicit object : an instance of GrailsPluginManager
Eg: Hibernate plugin checks for presence of controllers plugin for some decision making.
if (manager?.hasGrailsPlugin("controllers")) {
// DO something
}
![Page 39: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/39.jpg)
Adding our own Artefact Types
![Page 40: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/40.jpg)
Adding our own Artefact Types
Steps for introducing a custom Artefact:
1. An implementation of ArtefactHandler (Can use ArtefactHandlerAdapter as base)
2. Each Artefact must implement GrailsClass
3. def artefacts = [ org.somewhere.MyArtefactHandler ] in plugin descriptor.
See by Example:
Quartz plugin’s ArtefactHandler
![Page 41: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/41.jpg)
Releasing our plugin
![Page 42: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/42.jpg)
Releasing our plugin
1. Register on grails.org
2. Fill out this form
3. Provide good documentation for the users to get started.
4. Once approved, install the release plugin in the plugin application
5. grails publish-plugin --stacktrace
6. Once successful, the plugin will be published in the grails plugin
repository. Users will be able to install it directly from Grails Plugin portal
by adding the dependency in BuildConfig.groovy
![Page 43: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/43.jpg)
References and further reading
http://grails.org/doc/2.2.2/guide/plugins.html#creatingAndInstallingPlugins
https://github.com/grails-plugins/grails-quartz
https://github.com/gpc/grails-mail/
http://www.slideshare.net/mjhugo/building-grails-plugins-tips-and-tricks
![Page 44: Grails plugin development](https://reader037.vdocuments.us/reader037/viewer/2022110119/555874dad8b42aaa7e8b5376/html5/thumbnails/44.jpg)
thankyou