Thursday, March 13, 2008

Dynamic Method Calls with Groovy

Thanks to some help from James Lorenzen, Chad Gallemore and Travis Chase, ...

A couple of days ago I found myself iterating through a set of key=value pairs, and for each one calling a setter method on another object. In order to know which setter method to call, I had to examine the key. That's when it hit me... What if I could use the key to generate the setter method to call. Check this out.

I've got a simple bean with 2 member variables: username and password. There are corresponding setter methods: setUsername() and setPassword().


class UserBean {
private String username;
private String password;

void setUsername(String username) {
this.username = username
}

void setPassword(String password) {
this.password = password
}
}

Here I have a HashMap that I want to iterate through. It just so happens the keys in the map entries correspond exactly to the member variables of my simple bean. So, instead of examining each key to decide what setter method to call, I can do this:

import junit.framework.TestCase
public class DynamicMethodBuildingTest extends TestCase {

void testBuildMethodsBasedOnMapKeys() {

def testMap = new HashMap();
testMap.put("username","chad")
testMap.put("password","asdfasdf")

def userbean = new UserBean();

testMap.entrySet().each { entry ->
userbean."$entry.key" = entry.value
}
}
}

At this point I'm not really building the method that is being called. I'm building the property name. So, let's look at actually building a method call.

I've added 2 methods to my UserBean: login() and logoff().

void login() {
println username + " has Logged In"
}

void logoff() {
println username + " has Logged Off"
}

Let's test calling these 2 methods dynamically.

void testExecuteUserAction() {
def userActions = ["login", "logoff"];

def userbean = new UserBean()
userbean.username = "chad"

userActions.each { action ->
userbean."$action"()
}
}

Here's the output:

chad has Logged In
chad has Logged Off

Well, that's all it takes. And if you're asking, "What about a method that takes parameters?"... simply put your parameters inside the parenthesis. It may look something like this:

userbean."$action"(username)


Now I wonder, what would it take to accomplish this in Java?

Wednesday, March 5, 2008

Free Travel to Java Symposium 08

Since travel budgets seem to hinder conference attendance quite often, The Server Side is offering a raffle to win free airfare and hotel for the conference. And before you ask... No, you don't have to register for the conference to enter. Just sign up for the raffle. If you win, then worry about convincing your project manager to pay for the conference itself.

And... it's in Vegas!

Good Luck!