Reputation: 86
I want to show persistentProperties value invoked by doWithDynamicMethod on some plugin
with the following code, i managed to intercept save and update method on domain classes and see their output when they tried to save an object.
But i couldn't print the content of persistentProperties (maybe because i'm a noob on groovy and grails, therefore i didn't familiar with the syntax on groovy reflection.
Anyone could help ?
Following is my code :
def doWithDynamicMethods = { ctx ->
// TODO Implement registering dynamic methods to classes (optional)
application.domainClasses.each { gc ->
def domainClass = gc.clazz
domainClass.metaClass.invokeMethod = { name, args ->
if (name == 'save' || name == 'update')
delegate.log.info " ${delegate.class.name}.$name() args: $args"
new DefaultGrailsDomainClass(delegate.class).persistentProperties.each{ property ->
delegate.log.info "printing properties => "+ property.name+ " "
}//end persistentProperties.each
}//endmetaClass.invokeMethod
} //end domainClasses.each
}//end doWithDynamicMethod
Upvotes: 0
Views: 1578
Reputation: 1854
If I understand what you're trying to do, your code is currently listing the persistentProperties
which are associated with the domain class itself. To actually get the value of the property you need to pass the property name.
For instance, if you have the following domain class:
class Book {
String title
String lang
}
If you're saving a new Book
like so:
def b = new Book(title: 'Hemingway', lang: 'en-us').save()
Your code should print out something like this:
printing properties => title
printing properties => lang
If you want it to print something like this:
printing properties => Hemingway
printing properties => en-us
Then you'll have to access the property from the obj itself:
def doWithDynamicMethods = { ctx ->
application.domainClasses.each { gc ->
def domainClass = gc.clazz
domainClass.metaClass.invokeMethod = { name, args ->
def domainObj = delegate
if (name == 'save' || name == 'update') {
new DefaultGrailsDomainClass(domainObj.class).persistentProperties.toList().each { property ->
domainObj.log.info "printing properties => " + domainObj[property.name]
}
}
def called = domainClass.metaClass.getMetaMethod(name, args)
called?.invoke(domainObj, args)
}
}
}
There are some other gotchas. The variable delegate
is special to each closure. If you actually are running it you might not have seen the "printing properties..." log messages at all because in the call to delegate.log.info
inside the each
closure delegate
refers to the closure enclosing class. Also if you're going to read the properties from the domainObj
then you should make sure that it is inside the name if clause or else you'll make call into invokeMethod
again.
Finally, you should get the metaMethod that was originally being called and invoke it or else it won't actually save/update.
Upvotes: 2