viewing dynamic methods grails

Grails reminds me of those Anton Chekov stories I used to enjoy. A lot of fun, but tough to remember the plethora of characters introduced at different parts of the story, in the case of grails, it is methods added via meta-programming. Each of these methods add an important functionality, but it is tough to guess where the implementation source is and where this method was added.

For example we know every domain class has a list method, but where is it added to the domain class and which class actually backs the list method implementation. If we had information about where it was added in this case HibernateGrailsPlugin, a quick browse through the source would let us know that ListWithFilterMethod is our points of interest.

So I wanted something that for a domain class would give me method listings, with the one for list like


list

public static Object list()
Added by HibernatePluginSupport$_addQueryMethods_closure44

This tells me that list method is added by addQueryMethod of HibernateGrailsPlugin. I can easily find from the source then that ListWithFilterMethod provides the list implementation. The next step is to add a controller and some ui which would help me show such information about any class (Domain, Controller or any other groovy class). The class name could be passed as a request parameter, the ui could be made via jquery so that this fits in as an additional floating div over my existing ui.

Thanks to the simplicity of grails, all this controller has to do is :

  1. Load the class from the parameter name, get its meta data
  2. Iterate through the meta methods, collecting the source from the closure or cached method declaring class and pass it to the ui as json.

The code for doing this could be something like

def metaClass =GrailsUtil.getMetaClass(params.clazzName)
metaClass?.getMethods().each{
    if (it instanceof ClosureStaticMetaMethod) {
       list.add(new MethodInfo(it.name, it.closure.class.simpleName, extractMethodName(it)))
    } else if (it instanceof ClosureMetaMethod) {
       list.add(new MethodInfo(it.name, it.doCall?.cachedMethod?.declaringClass.simpleName, extractMethodName(it)))
    } else {
       list.add(new MethodInfo(it.toString(), null, null))
    }
}
list.sort()
render list as JSON

The end result looks something like

MethodInfo

I call it EGDoc, added it as a floating layer so that it does not come in the way of normal functioning of the application, of course is enabled when the environment is development.

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

Came across your post and I think this is a brilliant idea. Had been thinking about doing something like this for a while. Would you be so kind as to share your code to do this. You shared samples but I’d like to know if you would be willing to share the whole solution, especially the ui piece that deals with the display.

Thanks for your post,

Stephane

We kill any project that does not generate enough traction in its first six months of existence. Unfortunately this was one such project, so I don’t have the complete source code in our repository. As far as I remember, I let jquery tabs do most of the heavy lifting, with modifications to the main template page to have this div displayed on all pages. Will try to find any local copies and upload them, but don’t count on that :)

Leave a comment

(required)

(required)