The Kaptain on … stuff

16 Dec, 2009

Jira Grails Plugin

Posted by: TheKaptain In: Development

I set out to explore some of the Atlassian API’s this week, along with a test drive of Jira 4, and ended up developing a simple XML-RPC plugin for Grails. Utilizing little more than the Groovy XMLRPC library I was able to implement a client service for the Jira XmlRpcService in minutes.

Nothing terribly complicated going on for this plugin. Aside from the XMLRPC library and one more jar it depends upon there’s a service which implements calls for all of the methods on the XmlRpcService interface and a ‘helper’ class that makes using it a little easier(removes the need to pass the host name into each method). And any controller injected with the service gets a withJira(hostname, Closure) method which wraps the ‘helper’ class. This might not be the optimal way to do things, but I was looking for some better experience with MOP’ing in Groovy along with this little project so it worked out perfectly for me.

The method added to Controller classes just creates a ‘helper’ and sets it as the delegate for the closure.

[groovy language=”true”]
cClass.metaClass.withJira = {String hostname, Closure closure ->
def helper = delegate.jiraXmlRpcService.createHelper(hostname)
closure.setDelegate(helper)
closure.setResolveStrategy(Closure.DELEGATE_FIRST)
closure()
}
[/groovy]

Calling the withJira method looks like this, along with minimal exception handling:

[groovy language=”true”]
try
{
def projects, priorities, serverInfo
withJira(jiraInstance.baseUrl) {
def token = login(jiraInstance.userName, jiraInstance.password)
serverInfo = getServerInfo(token)
priorities = getPriorities(token)
projects = getProjectsNoSchemes(token)
logout(token)
}
[jiraInstance: jiraInstance, projects: projects, priorities: priorities, serverInfo: serverInfo]
}
catch (e)
{
flash.message = "Failed to load data from ${jiraInstance.baseUrl}"
redirect(action: "list")
}
[/groovy]

The ‘helper’ class itself represents an experiment with the Groovy ‘methodMissing’ behaviour. The idea is to store the ‘hostname’ for a series of calls against the stateless service and add that as the first parameter for all wrapped methods. It was simple and quick, but right off the bat you lose the ability to use IDE syntax completion support on this object. I thought another possibility here would be to use the @Delegate annotation on the service and/or Closure currying to add the additional ‘hostname’ parameter to methods.

[groovy language=”true”]
class JiraXmlRpcServiceHelper
{
def hostname
def JiraXmlRpcService service

def methodMissing(String name, args)
{
assert hostname && service
def method = service.metaClass.methods.find {it.name == name}
if(!method)
{
throw new NotImplementedException("The $name method is not implemented for ${this.getClass()}")
}

def newArgs = [hostname]
args.each{newArgs << it}
return method.invoke(service, newArgs as Object[])
}
}
[/groovy]

This plugin works with Grails 1.2.0.RC1 and represents about 8 hours of work all told – and a lot of fun to make! Jira 4 is not too shappy either, especially with the GreenHopper plugin. But that’s a post for another day.

A special thank you to Grails in Action and this article by Ted Naleid – both were extremely helpful putting this together. If you care to download it and take a spin here it is. Feedback is always welcome!

[download id=”1″]

Reblog this post [with Zemanta]

3 Responses to "Jira Grails Plugin"

1 | Jesse Gibbs

January 8th, 2010 at 7:55 am

Avatar

Hi Kelly,

It would be great if you can add your JIRA Grails plugin to http://plugins.atlassian.com. We’ll promote it on the JIRA blog that gets thousands of hits per week!

2 | TheKaptain

January 8th, 2010 at 10:43 am

Avatar

Thanks Jesse! I still have a few more enhancements I’d like to add before I release it widely; need to figure out the best way to handle Controller class reloading.
I was planning to release it(eventually) on http://www.grails.org/plugin/home , which already has a confluence plugin ( http://www.grails.org/plugin/confluence -if you didn’t already know), but I don’t see why that couldn’t be synced up with the Atlassian plugin library.

🙂

3 | manasa

February 14th, 2012 at 3:41 am

Avatar

Is this GRAILS plugin dded into atlassian.com.

Will this plugin supports dual or multiple axis charts?

Will this plugin supprot JIRA 4.4?

Comment Form