thejavajar

{ java, groovy, flex, python, ruby }

Flower

Posts Tagged ‘Groovy’

VXML and Groovy’s MarkupBuilder

For the last ~1.5 years I have been working with IVR applications. The framework we use is Java based and we use an Eclipse based IDE with a nice drag and drop editor to create the application’s call flow. The IVR application is packaged into a .war or .ear file by the IDE and we deploy the application to a Web container like Tomcat. The IVR is then pointed at the application’s entry point URL. The core flow is mapped into Servlets and each request into the application generates VXML (Voice XML) that is interpreted by the actual IVR which is responsible for handling call control and communicating with the other telephony technologies.

I think there could/should be a way to use Groovy’s MarkupBuilder and most likely Gaelyk to create IVR applications with less ceremony than using the drag and drop editor. We can create static VXML very simply with Groovy’s MarkupBuilder:

import groovy.xml.MarkupBuilder

def writer = new StringWriter()
def vxml = new MarkupBuilder()

vxml.vxml {
    field (name:"color") {
        grammar ("red | green | blue")
        prompt (count: 1, "Say red, green or blue.")
        prompt (count: 2, "Please say red, green or blue.")
        noinput (count: 1) {
            prompt ("I didn't hear you." )
            reprompt ()
        }
        noinput (count: 2) {
            prompt ("Sorry, I still didn't hear you.")
            reprompt ()
        }
        nomatch (count: 1) {
            prompt ("I didn't understand you." )
            reprompt ()
        }
        nomatch (count: 2) {
            prompt ("Sorry, I still didn't understand you.")
            reprompt ()
        }
    }
}

writer.toString()

Here is the output of the above:

<vxml>
  <field name='color'>
    <grammar>red | green | blue</grammar>
    <prompt count='1'>Say red, green or blue.</prompt>
    <prompt count='2'>Please say red, green or blue.</prompt>
    <noinput count='1'>
      <prompt>I didn't hear you.</prompt>
      <reprompt />
    </noinput>
    <noinput count='2'>
      <prompt>Sorry, I still didn't hear you.</prompt>
      <reprompt />
    </noinput>
    <nomatch count='1'>
      <prompt>I didn't understand you.</prompt>
      <reprompt />
    </nomatch>
    <nomatch count='2'>
      <prompt>Sorry, I still didn't understand you.</prompt>
      <reprompt />
    </nomatch>
  </field>
</vxml>

Then, if a nice, simple DSL (Domain Specific Language) is designed for building IVR applications with Groovy, we can then simplify the craft of creating IVR applications. Plus, we would gain the productivity of using Groovy when calling Web services and databases to provide dynamic data for the application. Just a crazy thought.

Having Fun with Groovy

I love browsing over to Groovy Console from time to time to check out scripts that have been recently published. It is a great place to learn Groovy or just have fun with Groovy without having to install anything. In the script below, I wanted to multiply two lists of Strings together so while playing around at the Groovy Console site I wrote:

java.util.ArrayList.metaClass.multiply = { e ->
    def list = new ArrayList()
    delegate.each { a ->
        e.each {
            list.add(a + it)
        }
    }
    list
}

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]

x * y

Now, there may be a better way of handling this in Groovy, but I get the result I am expecting by implementing the multiply method for the ArrayList MetaClass in the top part of the script.

Then I create my lists, x and y, and multiply (*) them together. Nothing too crazy going on here but this demonstrates the power that Groovy can provide programmers with very little effort. Here is the result:

[k1v1, k1v2, k1v3, k2v1, k2v2, k2v3, k3v1, k3v2, k3v3]

Update:

A few more elegant solutions posted at the Groovy Console site.

Shorter version.*

java.util.ArrayList.metaClass.multiply = { e ->
delegate.collect { a -> e.collect { a + it } } .flatten()
}

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]

x * y

Another version.*

java.util.ArrayList.metaClass.multiply = {
[delegate, it].combinations().collect { a -> a[0] + a[1] }
}

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]

x * y

No MOP version.**

x = ["k1", "k2", "k3"]
y = ["v1", "v2", "v3"]
[x, y].combinations()*.join()

*Courtesy of Paul Holt.
**Courtesy of paulk_asert.

Groovy Metaprogramming: propertyMissing

The other day, while working on a Java project, I realized that I could implement an application requirement quite quickly by extending a current domain object and adding an attribute. This is an enterprise wide, industry standard domain object model so I couldn’t just add the attribute to the domain object without cutting through some red tape. Plus, it was an attribute that I needed for my application and it would most likely have no use in other projects. So, I had something like this:

public class Policy {

	private String policyNumber;
	private Double value;
	private Double interestRate;

	/* getters and setters */
        ....
}

Then to get things done, I went ahead and created:

public class MyPolicy extends Policy {

	private String myNewProperty;
	private Policy p;

	public MyPolicy(Policy policy) {
		this.p = policy;
	}

	/* getters and setters */
        ....
}

Now, I could fulfill the requirement with ease because I now had a Policy object with the extra attribute I needed, myNewProperty, all in the MyPolicy object. I could now handle the Policy returned from the Web service call and pass it into the MyPolicy constructor, do some work to create an instance of MyPolicy with a Policy object, derive the value of myNewProperty and then send it on to a view for example. Nice, I think that will work for my application.

Later, I thought about how nice it would have been if the Policy object was implemented with Groovy. Then I could take advantage of Groovy’s metaprogramming features like propertyMissing. When I have propertyMissing in my languageĀ arsenal, I can create the Policy object like so:

class Policy {

	def properties = Collections.synchronizedMap([:])

	String policyNumber
	Double value
	Double interestRate

	def propertyMissing(String name, value)  { properties[name] = value }

	def propertyMissing(String name) { properties[name] }
}

In the implementation above, the propertyMissing(String name, value) method is called when trying to set a value, myNewProperty, that doesn’t exist in the Policy object. The propertyMissing(String name) method is called when trying to get a property, myNewProperty, that doesn’t exist in the Policy object. By default, the propertyMissing(String name) will return null if the value was never initialized or never dynamically created. Yeah, it is an incredible feature. What is really nice is that I didn’t have to create the MyPolicy object at all! In the Groovy world I could write the following:

def p = new Policy()

p.policyNumber = "12345678"
p.value = 12000.00
p.interestRate = 2.3

println p.policyNumber
println p.value
println p.interestRate

/* new property */
p.myNewProperty = "Active"

println p.myNewProperty

Later on I could even write:

/* another new property */
p.myOtherNewProperty = "Wow"

println p.myOtherNewProperty

This would save me some time and now because the Policy object is expandable, other applications that need to extend the Policy object, for application purposes, will be able to utilize these features. I am convinced, Groovy IS productivity for Java.

Groovy and Closures

Happy New Year! So it is 2010 and you still haven’t looked at Groovy or had fun developing with Closures? It is time to give it a try. Download Groovy (currently 1.7), setup a GROOVY_HOME variable, and add GROOVY_HOME/bin to your system path. Now open up a text editor, I like Textmate on my Mac and Notepad ++ when I am on a Windows machine, and create a new file, something like ClosureFun.groovy. Now let’s get some coding done. First, let’s add a class:

class Person {
    def firstName
    def lastName
    def emailAddress
}

This is really not too difficult to understand, right? We have a class, Person, with three attributes; firstName, lastName and emailAddress. Now let’s create some instances of Person:

bob = new Person(firstName:"Bob", lastName:"Jones", emailAddress:"bob.jones@yahoo.com")
rob = new Person(firstName:"Rob", lastName:"Fake", emailAddress:"rob.fake@gmail.com")
ray = new Person(firstName:"Ray", lastName:"Real", emailAddress:"ray.real@gmail.com")
tom = new Person(firstName:"Tom", lastName:"Real", emailAddress:"tom.real@yahoo.com")
mike = new Person(firstName:"Mike", lastName:"Test", emailAddress:"mike.test@msn.com")
drew = new Person(firstName:"Drew", lastName:"Wilkins", emailAddress:"dwilkins@aol.com")

We now have six instances of Person; bob, rob, ray, tom, mike and drew. Groovy supports these Map-like constructors and they are given to us just like Java gives us a no arg constructor by default if we do not create a constructor for our Java class. We also get new Person(firstName:”value”), new Person(lastName:”value”), new Person(emailAddress:”value”), new Person(firstName:”value”, emailAddress:”value”)… and the other permutations. This feature is quite nice. Now let’s create a list of Persons:

def list = [bob, rob, ray, tom, mike, drew]

Maybe the Groovy syntax is a little different than Java, but it is pretty easy to see how, in the code above, to create a list of Persons. Now, we have this instance of list, as in java.util.ArrayList, that now contains our instances of Person. We have created a class Person, we have our six instances of Person and they all exist in a list. What now?

Well, I want to be able to print out the values of firstName and lastName of particular instances of Person that are in the list. I want to print out the Person instances in our list where the firstName value begins with “R”. Then I want to be able to print out the Person instances in our list where the emailAddress contains “yahoo”. Someone else wants to print out the Person instances where the last letter in lastName is “e” and their friend wants the Person instances where the last letter in lastName is “s”. Should I write a method for each scenario that will take a list as a parameter and loop through each value and check for our desired condition then print the firstName and lastName? Sure, why not?

def printPersonsWithFirstNameBeginingWithR(list) {
    list.each {
        if(it.firstName.startsWith("R")) {
            println "$it.firstName $it.lastName"
        }
    }
}

Our first method is done. If you are not familiar with Groovy, ‘list.each’ is like a ‘for’ loop in Java and ‘it’ is an implicit placeholder for each item in the list. In our case, ‘it’ represents a Person class. More information on syntax of Groovy can be found on the Groovy Web site.

def printPersonsWithEmailAddressContainingYahoo(list) {
    list.each {
        if(it.emailAddress.contains("yahoo")) {
            println "$it.firstName $it.lastName"
        }
    }
}

def printPersonsWithLastNameEndingWithE(list) {
    list.each {
        if(it.lastName.getAt(-1) == "e") {
            println "$it.firstName $it.lastName"
        }
    }
}

def printPersonsWithLastNameEndingWithS(list) {
    list.each {
        if(it.lastName.getAt(-1) == "s") {
            println "$it.firstName $it.lastName"
        }
    }
}

That would work, right? Yeah, we could then write some code to call each method passing in our list and we would get what we want. Cool, we’re done. Wait, we need to support another condition. We need to support a request to print out all Person instances in our list where the emailAddress contains “gmail”. Well, I guess we should write another method? Why not?

def printPersonsWithEmailAddressContainingGmail(list) {
    list.each {
        if(it.emailAddress.contains("gmail")) {
            println "$it.firstName $it.lastName"
        }
    }
}

In our case, we see a pattern emerging. The only thing that changes in each of the above methods is the name of the method and the conditional statement in the if block. Well, when we take advantage of Closures in Groovy we can ignore the 5 methods we wrote above and just write 1 method like the one below (yeah, 5 methods into 1):

def printPersons(list, clos) {
    list.each() {
        if(clos(it)) {
            println "$it.firstName $it.lastName"
        }
    }
}

The above method looks just like our other 5 methods but we have changed our input parameters. Now we are expecting a list and a Closure as arguments and we evaluate the Closure parameter in the if block as our conditional statement (Closures can do more than return true or false). So how do we call our re-factored, re-written method? We now call the method passing is our list as a parameter and because the Closure is the last argument in the printPersons method, we can create our conditional Closure within brackets as you can see here:

// firstName starts with 'R'
printPersons(list) { it.firstName.startsWith("R") } 

// emailAddress contains 'yahoo'
printPersons(list) { it.emailAddress.contains("yahoo") } 

// last letter of lastName is 'e'
printPersons(list) { it.lastName.getAt(-1) == "e" }

// last letter of lastName is 's'
printPersons(list) { it.lastName.getAt(-1) == "s" }

Without getting into all the syntax and semantics of Groovy, we use ‘it’ again because it is a special implicit variable in Groovy used quite often with Closures and other Groovy code structures. In our case, ‘it’ will represent each Person instance in the loop, ‘list.each’. Now when we need to add that last minute request, well, it is already supported! Just pass the new condition.

// emailAddress contains 'gmail'
printPersons(list) { it.emailAddress.contains("gmail") }

Very cool stuff. Now, we can combine everything in one file, like ClosureFun.groovy and run the script. There are plenty of articles and blog posts all over the Internet about Groovy and Closures. I have learned quite a bit by attending presentations by people like Venkat Subramaniam, Scott Davis, Guillaume LaForge, Graeme Rocher, Jeff Brown and a few others. At the end of the day, it is all about getting your hands on Groovy, so get out there and write some code!