Tuesday, September 07, 2010

Groovy Set or List

Below is a script that might be helpful to new Groovy developers. We sometimes have to be careful when we are working so closely with Java and Groovy at the same time. In this first block, I create a HashSet (java.util.HashSet) with a Collection as an argument to the Constructor:

def mySet = new HashSet(["test", "tester"])

assert mySet.size() == 2

mySet << "test"
mySet << "tester"

assert mySet.size() == 2


I then try to add duplicate entries ("test" and "tester"), using the << operator, into mySet which does not work and I verify this by asserting that mySet's size is still 2, as when it was instantiated.

Next, I instantiate an empty HashSet (java.util.HashSet) and then assign a collection of values to mySet. Again, I try to add (<<) duplicate entries ("test" and "tester") into mySet.

def mySet = new HashSet()

mySet = ["test", "tester"]

assert mySet.size() == 2

mySet << "test"
mySet << "tester"

assert mySet.size() == 2


In the above snippet, the second assertion fails. What? mySet is an instance of HashSet (java.util.HashSet)! How did this happen? Maybe, I should open a defect? Not so fast. We have to think about the dynamic (not static) nature semantics of Groovy. If we examine the line

mySet = ["test", "tester"]


and focus on the collection

["test", "tester"]

we should know that in Groovy

["test", "tester"].class

is an ArrayList (java.util.ArrayList) and thereafter so is the variable mySet. Now this might seem like a disappointment to Java developers who are starting to learn Groovy, but if we really want a unique collection of entries we can always utilize

mySet.unique()


to take care of this task for us or we can just instantiate HashSet and use the add method or << operator to add values to mySet.

def mySet = new HashSet()

mySet.add("test")
mySet << "tester"

assert mySet.size() == 2

Thursday, September 02, 2010

Why I Love Spring 2.5's PropertyPlaceholderConfigurer

I have been a big fan of Spring's PropertyPlaceholderConfigurer since 2006 when I could wire up a datasource bean, or any bean for that matter, with just some references to properties that I knew were going to be in place. A snippet from a Spring context file for example:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${my.db.driver}"/>
    <property name="url" value="${my.db.url}"/>  
    <property name="username" value="${my.db.username}"/>
    <property name="password" value="${my.db.password}"/>
</bean>


Now, I can provide PropertyPlaceholderConfigurer with a .properties file location(s) or I could depend on the properties existing as part of the runtime, like when using JBoss Application Server's property service. Then one day, I ran into a bit of an issue. Well, now I have an application with a properties file that has datasource connection information for each development region, DEV, TEST and PROD and the region is a 'prefix' on each property.

Something like...

DEV.my.db.driver
DEV.my.db.url
DEV.my.db.username
DEV.my.db.password

TEST.my.db.driver
TEST.my.db.url
TEST.my.db.username
TEST.my.db.password


... and so on. If you are packaging .properties files into your archive(.war, .jar, .ear), this does help your code be a bit more portable but I usually configure properties outside of an archive but we can't always have our way. So, now we have a special class that reads the properties file and the region variable from SystemProperties as the region variable, SDLC_REGION, is set in each development region as a VM argument.

-DSDLC_REGION=DEV


And that works great. We can leave our Spring context alone and everything works like we need it to. But, I am always trying to reduce classes or utilities(.jar files) that are no longer needed in our applications. So, I took a look back into Spring 2.5's PropertyPlaceholderConfigurer and low and behold, there is a better way to do things. Check it out. Here is my Spring context file now:

<context:property-placeholder location="classpath:db.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${${SDLC_REGION}.my.db.driver}"/>
    <property name="url" value="${${SDLC_REGION}.my.db.url}"/>  
    <property name="username" value="${${SDLC_REGION}.my.db.username}"/>
    <property name="password" value="${${SDLC_REGION}.my.db.password}"/>
</bean>


Now, the VM argument, SDLC_REGION, exists in each environment and it can be a part of our PropertyPlaceholderConfigurer expression. We can now load the correct property for each development region from the packaged .properties file without depending on our utility class anymore. Really cool stuff and again, beautiful work from the people at SpringSource.

Wednesday, September 01, 2010

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.