Groovy salutes you!
Some time ago in one of my previous projects, we had to generate customer salutations in emails and SMS texts in various ways, like these example show:
"Dear Mr. John Miller", "Dear Mrs. Dr. Miller", "Miller, John"
The task was nasty, because sometimes the user object had a firstname or a title, but some of the fields were optional, so that it could result in:
"Dear Mr. null Miller" (when firstname was null) or
"Miller, " (when firstname as "")
It showed, that a utility class would be useful, that helps to generate the salutation strings and fill the gaps between “firstname”, “lastname”, “title” etc. only, when the parts are not empty. A java implementation named “SalutationUtil” was implemented, consisting of a 230 line class “SalutationParser”, that parsed an expression string and a 140 line class “SalutationUtil” to present an API. We used a ResourceBundle to fill the “Dear” and “Mr.” parts according to the language to be used and the gender of the person to be addressed.
Now, in our current project, we had the same problem and I was thinking to reuse the java implementation. No problem, because although we are using Grails/Groovy nowadays, the “SalutationUtil” would still be compatible. After some minutes of looking at the java code, I dropped it and replaced the whole “SalutationUtil” and the parser-class by a 40 line Groovy implementation “Salutation.groovy”, that shows a much simpler approach to the same problem using a Groovy closure to create the salutation string. Here is the code, may it be useful for the rest of the world:
class Salutation { private StringBuilder buf = new StringBuilder() private boolean touched, said String defaultSalutation = '' static format(Closure builder, String defaultSalutation = '') { return new Salutation(defaultSalutation: defaultSalutation).salute(builder) } String salute(Closure builder) { with builder return toString() } String toString() { if (touched) { return buf.toString() } else { return defaultSalutation } } void add(def text) { if (text) { touched = true buf.append(text) said = true } else { said = false } } void gap(def text) { if (text && said) { touched = true buf.append(text) said = false } }}// Example 1def person = [firstName: 'Peter', lastName: 'Miller', title: 'Dr', gender: 'male']def salutation = Salutation.format({ add(person.gender=='male':'Mr.' ?'Mrs.') add(person.title) gap(' ') add(person.firstName) gap(' ') add(person.lastName) }) // results in => "Mr. Dr Peter Miller"// Example 2def person = [firstName: 'Peter', lastName: 'Miller']def salutation = Salutation.format({ add(person.title) gap(' ') add(person.lastName) gap(', ') add(person.firstName) }) // results in => "Miller, Peter"// Example 3def person = [lastName: 'Miller']def salutation = Salutation.format({ add(person.title) gap(' ') add(person.lastName) gap(', ') add(person.firstName) }, "customer") // results in => "Miller"// Example 4def person = [:]def salutation = Salutation.format({ add(person.title) gap(' ') add(person.lastName) gap(', ') add(person.firstName) }, "customer") // results in => "customer"
A salute to Groovy! To write this post took more time than to implement the code.

