Reputation: 99
If I have a groovy class like this:
class WebSession{
String firstName
String lastName
String email
}
I want to be able to use the automatic setters to set the value. For example:
WebSessionuser = new WebSession()
webSession.firstName = 'John'
But have the setter it calls do extra stuff, like log something or persist the object to cache.
How would I do this without having to define all the setters manually? So far I have something like this, but I can't quite get it working:
webSession.properties.each{ key, value ->
if ( key != 'class' ) {
String methodName = "set${key.capitalize()}";
WebSession.metaClass[key]."${methodName}" = { -> delegate
System.out.println("Setting key: ${key}");
webSession[key] = delegate;
}
}
}
Also, I don't know if looping over the property names minus 'class' is hacky and there's a better way to get the declared fields.
Upvotes: 1
Views: 535
Reputation: 9885
You can intercept all the getters and setters by implementing void setProperty(String, Object)
and Object getProperty(String)
. Here's an example:
def a = new WebSessionDecorator(new WebSession())
a.firstName = 'John'
println a.firstName
class WebSession {
String firstName
String lastName
String email
}
class WebSessionDecorator {
private WebSession delegate
WebSessionDecorator(WebSession webSession) {
this.delegate = webSession
}
void setProperty(String name, Object value) {
println "LOG: Setting $name to $value"
delegate.setProperty(name, value)
}
def getProperty(String name) {
println "LOG: Returning $name"
delegate.getProperty(name)
}
}
The output looks like this:
LOG: Setting firstName to John
LOG: Returning firstName
John
The WebSessionDecorator
intercepts all property access, providing an opportunity for going whatever you want to do. Then, it delegates the property access to the actual WebSession
.
I chose to go with a decorator in order to avoid recurring calls to getProperty()
and setProperty()
, and to make it possible to use the decorator only when applicable. For example, you may not want to use it in a unit test.
Upvotes: 2