Loading...

Monday, August 30, 2010

Groovy Goodness: Convert Date to java.sql.Timestamp

Groovy adds many methods to standard Java classes we can use in our code. To convert a simple Date object to a java.sql.Timestamp we can simply use the toTimestamp() method on a Date object.

import static java.util.Calendar.*

// Create date object with specific year, month and day.
def date = new Date()
date.clearTime()
date.set year: 2010, month: AUGUST, date: 10

// Convert to java.sql.Timestamp.
def sqlTimestamp = date.toTimestamp()
assert 'java.sql.Timestamp' == sqlTimestamp.class.name
assert '2010-08-10 00:00:00.0' == sqlTimestamp.toString()

Thursday, August 26, 2010

Groovy Goodness: Store Closures in Script Binding

We have several ways to run (external) Groovy scripts from our code. For example we can use GroovyShell and the evaluate() method. If we want to pass variables to the script to be run we must create a Binding object and assign values to the variables and in our script we can use the variables. But if we assign closures to the variables we have methods available in our scripts. We can use it for example to define a DSL externally from the script that uses the DSL.

First we create a script with a simple DSL for sending text to the console or to a file:

// File: Output.groovy
console 'Groovy is great'

file('result.txt') { out ->
    out << 'Yes it is!'
}

Now we define the Groovy script that reads the script file and executes it:

// File: RunOutput.groovy
// Define DSL methods as closure variables in the binding.
def binding = new Binding()
binding.console = { String message ->
    println message
}
binding.file = { String fileName, Closure outputCode ->
    def outputFile = new File(fileName)
    outputFile.withWriter { writer ->
        outputCode.call writer
    }
}

// Create shell with the new binding.
def shell = new GroovyShell(binding)
def script = new File('Output.groovy')

// And execute
shell.evaluate script

We get the following output when we run the script:

$ groovy RunOutput
Groovy is great

And in the current directory we have a new file result.txt with the following contents: Yes it is!.

Wednesday, August 25, 2010

Groovy Goodness: Resolve Module Location with Grape

Grape in Groovy is a great way to define dependencies in our scripts and let Groovy download them automatically for us. We also can use the command-line tool grape to resolve the location of modules on our system. We use the resolve command to get the absolute path to our dependency, but we can even pass extra arguments like -shell and -dos and we get the location as a CLASSPATH environment variable. If we use -ant we can use the output in a ANT build file. Or -ivy to get the information in Ivy XML format.

$ grape resolve commons-lang commons-lang 2.5
/Users/mrhaki/.groovy/grapes/commons-lang/commons-lang/jars/commons-lang-2.5.jar

$ grape resolve -dos commons-lang commons-lang 2.5
set CLASSPATH=/Users/mrhaki/.groovy/grapes/commons-lang/commons-lang/jars/commons-lang-2.5.jar

$ grape resolve -shell commons-lang commons-lang 2.5
export CLASSPATH=/Users/mrhaki/.groovy/grapes/commons-lang/commons-lang/jars/commons-lang-2.5.jar

$ grape resolve -ant commons-lang commons-lang 2.5
<pathelement location="/Users/mrhaki/.groovy/grapes/commons-lang/commons-lang/jars/commons-lang-2.5.jar">

$ grape resolve -ivy commons-lang commons-lang 2.5
<dependency org="commons-lang" name="commons-lang" revision="2.4">

Tuesday, August 24, 2010

Groovy Goodness: Process Map Entries in Reverse

Since Groovy 1.7.2 we can loop through a Map in reverse with the reverseEach(). The order in which the content is processed is not guaranteed with a Map. If we use a TreeMap the natural ordering of the keys of the map is used.

def reversed = [:]
[a: 1, c: 3, b: 2].reverseEach { key, value ->
    reversed[key] = value ** 2
}

assert [b: 4, c: 9, a: 1] == reversed

// TreeMap uses natural ordering of keys, so 
// reverseEach starts with key 'c'.
def tree = [a: 10, c: 30, b: 20] as TreeMap
def reversedMap = [:]
tree.reverseEach {
    reversedMap[it.key] = it.value * 2
}
assert [c: 60, b: 40, a: 20] == reversedMap

Monday, August 9, 2010

Groovy Goodness: Subtracting Map Entries

Groovy 1.7.4 adds the minus() method to the Map class. The result is a new map with the entries of the map minus the same entries from the second map.

def m1 = [user: 'mrhaki', age: 37]
def m2 = [user: 'mrhaki', name: 'Hubert']
def m3 = [user: 'Hubert', age: 37]

assert [age: 37] == m1 - m2
assert [user: 'mrhaki'] == m1 - m3

Groovy Goodness: Simple File Renaming

Groovy has a lot of simple useful methods to make every day life easier. In Groovy 1.7.4 we can use the renameTo() method on a File object. We pass a String argument with the new name of the file.

def file = new File('test.groovy')
file.text = 'simple content'
file.renameTo 'newname.groovy'

def newFile = new File('newname.groovy')
assert newFile.exists()
assert 'simple content' == newFile.text

Groovy Goodness: Groovy Truth for Simple Type Arrays

Since Groovy 1.7.4 we can use simple type arrays in a conditional context. If the array is empty we get false, otherwise true is returned. Support for byte, short, int, long, float, double, char and boolean type arrays is added to Groovy. This functionality already worked for Object arrays, but now also for simple type arrays.

def bytes = [] as byte[]
def ints = [1,2,4] as int[]
def floats = [] as float[]
def booleans = [true, false] as boolean[]

assert !bytes
assert ints
assert !floats
assert booleans

Groovy Goodness: Intersect Maps

Since Groovy 1.7.4 we can intersect two maps and get a resulting map with only the entries found in both maps.

def m1 = [a: 'Groovy', b: 'rocks', c: '!']
def m2 = [a: 'Groovy', b: 'rocks', c: '?', d: 'Yes!']

assert [a: 'Groovy', b: 'rocks'] == m1.intersect(m2)

assert [1: 1.0, 2: 2] == [1: 1.0, 2: 2].intersect([1: 1, 2: 2.0])