Saturday, May 17, 2008
Introducing JugList.net
JugList.Net is a searchable directory of Java User Groups around the world.
You can search for a JUG (Java User Group) by name, city, state/province or country. If you still can't find a JUG in your area, there is a link to an article, by yours truly, that gives some tips on starting your own group.
Java User Groups are a valuable resource for honing your craft and building your career. They also provide a great way for experienced programmers to give a little back to the community. If you are not involved in a JUG yet, then check out juglist.net and find one near you.
Friday, May 16, 2008
Another way to use Groovy in the Enterprise
In this example we'll build a utility class that will use convention to turn an SQL select statement into a List of data transfer objects.
Our goal here is to take an SQL statement and a Class, execute that statement and use the results to populate instances of the Class. We will assume the convention of camel case for object properties and underscores for database fields, so that a field called LAST_NAME would be mapped to a property called lastName. We will also assume that the select statement will only return fields that have a corresponding property in the Class.
So let's see what this might look like:
static Collection getData(String query, Class clazz, Connection con){
def field = ''
def result = []
def sql = new Sql(con)
sql.rows(query).each {row ->
def dto = clazz.newInstance()
row.keySet().each{
field = toCamelCase(it)
dto."${field}" = row."${it}"
}
result << dto
}
result
}
After defining a few variables, we create our groovy.sql.Sql object using the constructor that takes a Connection. This will allow us to use Connections provided by an application server such as WebLogic or WebSphere. We could easily change this method to take advantage of the other constructors.
Next we'll call the rows method of the Sql class, which will execute the SQL statement and return an ArrayList of GroovyRowResults. Now we'll iterate through this ArrayList and create a new instance of our DTO class for each row. GroovyRowResult implements the Map interface so we can loop through its keys with row.keySet().each. This will give us each of the fields in that row and we will turn them into property names with a call to the toCamelCase() method (which we'll look at shortly). Notice how we take advantage of GStrings to dynamically access properties of our DTO as well as keys of the row map. After we assign each of the fields in the row to properties of the DTO instance we add it to the result List. When the loop is done we just return the List. Obviously, more can be done to make this more robust and more flexible, but it's pretty amazing how easy it was to build a Groovy class that can replace tons of repetitive Java code.
Let's take a look at how we could use this class from a Java project:
...
Connection con = getConnectionFromPool();
String query = "SELECT FIRST_NAME, LAST_NAME, EMAIL FROM MEMBER";
Collection members = GroovyData.getData(query, MemberDTO.class, con);
...
That's all there is to it.
Now let's take a quick look at the toCamelCase() method we mentioned above. This doesn't directly have anything to do with the purpose of this post, but I am hoping that someone might see this and offer a groovier way to do the same thing. Basically the goal is to take a database field name such as LAST_NAME and turn it into a camelCase string like lastName. Here's how I did it:
static String toCamelCase(String val){
def sb = new StringBuffer()
Boolean newWord = false
val.toLowerCase().each{
if (it == '_')
newWord = true
else{
if (newWord){
newWord = false
sb << it.toUpperCase()
}
else
sb << it
}
}
sb.toString()
}
I was sure there was a groovier way to do this and, sure enough, Andres Almiray came up with this awesome improvement:
static String toCamelCase(String val){
def result = val.split("_").collect { word ->
word[0].toUpperCase() + word[1..-1].toLowerCase()
}.join("")
result[0].toLowerCase() + result[1..-1]
}
Thanks Andres! And if that wasn't groovy enough, Ted Naleid came up with this cool mix of regular expressions and meta-programming. Good stuff Ted!
def camelCaseConverter(orig) {
orig.toLowerCase().replaceAll(/_(\w)?/) { wholeMatch, firstLetter ->
firstLetter?.toUpperCase() ?: ""
}
}
String.metaClass.toCamelCase = {->
camelCaseConverter(delegate)
}
Thursday, May 1, 2008
Groovy and Grails at JavaOne
Then for the rest of the week a groovy search in the Content Catalog turned up the following list:
ID | Session Title | Speaker(s) | Date / Time | Room | |
TS-5771 | The Duke and the Elephant: PHP Meets Java™ Technology--the Best of Both Worlds | Rob Nicholson, IBM |
| Esplanade 301 | |
TS-5764 | Grails in Depth | Guillaume Laforge, G2One, Inc., Graeme Rocher, G2One Inc |
| Esplanade 307-310 | |
BOF-5613 | Jersey: RESTful Web Services Made Easy | Jakub Podlesak, Sun Microsystems |
| Esplanade 307-310 | |
PAN-5435 | The Script Bowl: A Rapid-Fire Comparison of Scripting Languages | Guillaume Laforge, G2One, Inc., Charles Nutter, Sun Microsystems, Inc., Jorge Ortiz, Stanford, Raghavan Srinivas, Sun Microsystems, Inc., |
| Gateway 104 | |
TS-5572 | Groovy, the Red Pill: Metaprogramming--How to Blow the Mind of Developers on the Java™ Platform | Scott Davis, Davisworld Consulting, Inc. |
| North Mtg-121/122/124/125 | |
TS-5815 | Going Mobile with JavaFX™ Script Technology, Groovy, and Google Android | Mike Mannion, Canoo Engineering AG |
| Esplanade 301 | |
TS-6050 | Comparing JRuby and Groovy | Neal Ford, ThoughtWorks Inc. |
| North Mtg-121/122/124/125 | |
TS-5274 | Groovy on a Cloud: Testing Java™ Platform, Enterprise Edition (Java EE Platform) Applications on Amazon EC2 | Chris Richardson, Chris Richardson Consulting, Inc. |
| Gateway 104 | |
TS-6213 | Boldly Go Where the Java™ Programming Language Has Never Gone Before | Geert Bevin, Terracotta |
| North Mtg-121/122/124/125 | |
BOF-5102 | Cooking Your Own Groovy Builder: A Step Forward into Domain-Specific Languages | Andres Almiray, Oracle, Ixchel Ruiz, Clemente Camara y Asociados |
| Gateway 104 | |
BOF-5110 | Extending Groovy’s Swing User Interface in Builder to Build Richer Applications | Danno Ferrin, Intelligent Software Solutions, Inc., James Williams, Spatial Networks |
| Hall E 133 | |
TS-5793 | Groovy and Grails: Changing the Landscape of Java™ Platform, Enterprise Edition (Java EE Platform) Patterns | Guillaume Laforge, G2One, Inc., Graeme Rocher, G2One Inc |
| North Mtg-121/122/124/125 | |
TS-5693 | Writing Your Own JSR-Compliant, Domain-Specific Scripting Language | John Colosi, VeriSign, Inc.; David Smith, VeriSign Inc. |
| Esplanade 301 | |
TS-6457 | Choosing Your Java™ Technology-Based Web Framework: A Comparison | Richard Pack, Hyperic; Stacey Schneider, Hyperic |
| Esplanade 307-310 | |
TS-6606 | Patterns for Integrating Java™ and JavaScript™ Technology: Tales from the Front Lines | David Caldwell, David P. Caldwell, Inc. |
| North Mtg-121/122/124/125 | |
BOF-5101 | Boosting Your Testing Productivity with Groovy | Andres Almiray, Oracle;, James Williams, Spatial Networks |
| Gateway 102/103 | |
TS-5098 | Building Rich Applications with Groovy's SwingBuilder | Andres Almiray, Oracle;, Danno Ferrin, Intelligent Software Solutions, Inc. |
| Esplanade 305 | |
TS-6050 | Comparing JRuby and Groovy | Neal Ford, ThoughtWorks Inc. |
| Esplanade 303 | |
TS-6039 | Jython - Implementing Dynamic Language Features for the Java™ Platform Ecosystem | Jim Baker, Zyasoft, Tobias Ivarsson, Neo Technology |
| Esplanade 305 |
Well, if you read this far and if you happen to be wandering around the Pavillion on Tuesday afternoon at 3:30, I will be giving a mini-talk on Java User Groups at the java.net Community Corner. (That way I can say that I gave a presentation at JavaOne).