Search

Dark theme | Light theme

December 31, 2009

Groovy Goodness: Recursively Collect Elements

The collectAll() method of the Collection class is a Groovy extension to the standard Java classes. With this method we can transform values in a collection and the result is stored in a new collection. We have learned about the collect() method before. The collectAll() can apply the closure to the elements in the collection, but also to collections in the collection. So if we have nested collections we can use the collectAll() method to transform each element.

def list = [10, 20, 30, [1, 2, 3, [25, 50]], ['Groovy']]

assert [20, 40, 60, [2, 4, 6, [50, 100]], ['GroovyGroovy']] == list.collectAll { it*2 }
assert [20, 40, 60, [1, 2, 3, [25, 50], 1, 2, 3, [25, 50]], ['Groovy', 'Groovy']] == list.collect { it * 2 }
​

December 30, 2009

Groovy Goodness: Putting Our List in Reverse

Groovy has so many extra methods for lists to make life easier. For example we can reverse a list with the reverse() method. But we can also loop reverse through a list with reverseEach().

def list = [10, 20, 30]

assert [30, 20, 10] == list.reverse()

def result = []
list.reverseEach {
    result << it * 2
}

assert [60, 40, 20] == result

December 29, 2009

Groovy Goodness: What Character Are You?

Groovy adds a couple of methods to the Character class to determine of the character is a letter, digit, whitespace, upper- or lowercase.

def str = 'a1cB \n.9'
def characters = str.chars  // Convert to char[]

assert characters[0].isLetter()  // 'a'
assert characters[1].isDigit()  // '1'
assert characters[2].isLowerCase()  // 'c'
assert characters[3].isUpperCase()  // 'B'
assert characters[4].isWhitespace()  // ' '
assert characters[5].isWhitespace()  // '\n'
assert !characters[6].isLetterOrDigit()  // '.'
assert characters[7].isLetterOrDigit()  // '9'

December 28, 2009

Groovy Goodness: Powerful Assert

In Groovy 1.7 we get a lot of information if an assertion isn't true. Before we only could see the assertion was false, but now we get a breakdown of all components used in the assertion. For each component the return value is shown, so we can easily determine what component is responsible for the false assertion.

For example we run the following code:

def list = [1, 2, 3, 4, 5]
assert 4 == list.max() - 2

And the assert output is:

assert 4 == list.max() - 2
         |  |    |     |
         |  |    5     3
         |  [1, 2, 3, 4, 5]
         false

We notice how the output shows the contents of the list, the output of list.max() and the result of list.max() - 2.

December 27, 2009

Groovy Goodness: Apply Closure to All Element in a Collection with collect

We can apply a closure to all elements in a collection with the collect() method. The closure is executed for each element and the return value of the closure is the new element in the collection. We can put a lot of code in the closure, but we have to remember the last statement defines the return value and type for the element in the new collection.

class User {
    String username
    String language= 'Java'
    String toString() { "$username likes $language" }
}

def users = ['mrhaki', 'Hubert A. Klein Ikkink', 'Sample'].collect { new User(username: it) }
assert ['mrhaki likes Java', 'Hubert A. Klein Ikkink likes Java', 'Sample likes Java'] == users.collect { it.toString() }
// Last statement of collect closure is new list item.
def usersGroovy = users.collect { user ->
    if (user.username != 'Sample') {
        user.language = 'Groovy'
    }
    user  // Return user object so new list contains user objects!
}
assert ['mrhaki likes Groovy', 'Hubert A. Klein Ikkink likes Groovy', 'Sample likes Java'] == usersGroovy.collect { it.toString() }

// Last statement of collect closure is new list item.
// In this case we only return a String.
def usersClojure = users.collect { user ->
    user.language = 'Clojure'
}
assert ['Clojure', 'Clojure', 'Clojure'] == usersClojure

December 26, 2009

Gradle Goodness: Using Optional Ant Task in Gradle

Gradle uses Groovy's AntBuilder for Ant integration. But if we want to use an optional Ant task we must do something extra, because the optional tasks and their dependencies are not in the Gradle classpath. Luckily we only have to define our dependencies for the optional task in the build.gradle file and we can define and use the optional Ant task.

In the following sample we are using the scp Ant optional task. We define a configuration and assign the dependencies to this configuration. Then we can define the task and set the classpath property to the classpath of the configuration. We use asPath to convert the configuration classpath for the Ant task. In the sample we also see how we can ask for user input when the script is run. The passphrase for the ssh keyfile is a secret and we don't want to keep it in a file somewhere, so we ask the user for it. The Java method System.console() return a reference to the console and with readPassword() we can get the value for the passphrase.

// File: build.gradle

// We define a new configuration with the name 'sshAntTask'.
// This configuration is used to define our dependencies.
configurations {
    sshAntTask
}

// Define the Maven central repository to look for the dependencies.
repositories {
    mavenCentral()
}

// Assign dependencies to the sshAntTask configuration.
dependencies {
    sshAntTask 'org.apache.ant:ant-jsch:1.7.1', 'jsch:jsch:0.1.29'
}

// Sample task which uses the scp Ant optional task.
task update {
    description = 'Update files on remote server.'

    // Get passphrase from user input.
    def console = System.console()
    def passphrase = console.readPassword('%s: ', 'Please enter the passphrase for the keyfile')
        
    // Redefine scp Ant task, with the classpath property set to our newly defined
    // sshAntTask configuration classpath.
    ant.taskdef(name: 'scp', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.Scp',
            classpath: configurations.sshAntTask.asPath)
            
    // Invoke the scp Ant task. (Use gradle -i update to see the output of the Ant task.)
    ant.scp(todir: 'mrhaki@servername:/home/mrhaki',
            keyfile: '${user.home}/.ssh/id_rsa', 
            passphrase: passphrase as String, // Use phassphrase entered by the user.
            verbose: 'true') {
        fileset(dir: 'work') {
            include(name: '**/**')
        }
    }            
}

Written with Gradle 0.8.

Groovy Goodness: Using the OrderBy Comparator

The OrderBy class in Groovy implements the Comparator interface. We provide one or more closures to an OrderBy object, which are executed for comparing values. We can use this object whenever we need a comparator, for example if we invoke the sort() method on a collection.

class Language {
    String name
    boolean dynamic
    String toString() { "name: $name, dynamic: $dynamic" }
}

def languages = [
    new Language(name: 'Groovy', dynamic: true),
    new Language(name: 'Java', dynamic: false),
    new Language(name: 'Clojure', dynamic: true)
]

// We order first on dynamic property and then name property.
def orderByDynamicAndName = new OrderBy([{ it.dynamic }, { it.name }])
def sortedLanguages = languages.sort(orderByDynamicAndName)

assert 'Java' == sortedLanguages[0].name
assert !sortedLanguages[0].dynamic
assert 'Clojure' == sortedLanguages[1].name 
assert 'Groovy' == sortedLanguages[2].name
assert sortedLanguages[1].dynamic && sortedLanguages[2].dynamic

December 25, 2009

Groovy Goodness: Getting All Subsequences of a List

With Groovy 1.7 we can retrieve all subsequences from a collection with the subsequences() method. All possible subsequences of the elements in the list are returned.

def languages = ['Groovy', 'Clojure', 'Scala']

def sequences = languages.subsequences()

assert [['Clojure'], ['Scala'], ['Groovy']] == sequences.findAll { it.size() == 1 } as List
assert [['Clojure', 'Scala'], ['Groovy', 'Scala'], ['Groovy', 'Clojure']] == sequences.findAll { it.size() == 2 } as List
assert [['Groovy', 'Clojure', 'Scala']] == sequences.findAll { it.size() == 3}.toList()

December 24, 2009

Groovy Goodness: Looping Through Each Permutation in a Collection

Groovy 1.7 adds news methods to the standard Java classes. One of the new methods is eachPermutation(). With this method we can loop through all permutations of a collection and run a closure for the iterations. To get all permutations for a collection we can use the permutations() method.

def languages = ['Groovy', 'Clojure', 'Scala']

def result = []
languages.eachPermutation {
    result << it
}

assert 6 == result.size()
assert ['Groovy', 'Clojure', 'Scala'] == result[0]
assert ['Groovy', 'Scala', 'Clojure'] == result[1]
assert [['Clojure', 'Groovy', 'Scala'], ['Clojure', 'Scala', 'Groovy']] == result.findAll { it[0] == 'Clojure' }

// We can also get the complete list of permutations as Set.
def list = [true, false]
def permutations = list.permutations()
assert 2 == permutations.size()
assert [[false,true], [true,false]] as Set == permutations

December 23, 2009

Groovy Goodness: We Can Handle the Truth

In Groovy 1.7 we can coerse objects to a boolean. We only have to provide the method asBoolean() and return true or false. This means our object can be used in a conditional context without accessing any other methods or properties.

class User {
    String username
    boolean active

    boolean asBoolean() { 
        active
    }
}

assert new User(username: 'mrhaki', active: true)
assert !new User(username: 'mrhaki', active: false)

// We can also add the asBoolean method with metaClass.
String.metaClass.asBoolean = {
    delegate == /sure/
}
assert !'true'
assert 'sure'

December 22, 2009

Groovy Goodness: Implementing MetaClass Methods with Same Name but Different Arguments

Using the metaClass property of a class we can add new methods or override existing methods of the class. If we want to add a new methods that have the same name, but different arguments, we can use a shortcut notation. Groovy allows us to chain multiple leftShift() (<<) methods together.

String.metaClass.groovy << { Integer number ->
    delegate * number
} << { String s ->
    delegate + s
} << { ->
    delegate + ' Groovy rocks.'
}

assert 'GroovyGroovy' == 'Groovy'.groovy(2)
assert 'Hello world from Groovy' == 'Hello world'.groovy(' from Groovy')
assert 'It is true. Groovy rocks.' == 'It is true.'.groovy()

December 21, 2009

Groovy Goodness: Override and Use Old Implementation with Dynamic Methods

We can add new methods to classes with the metaClass property. But what if we want to use the old implementation for some cases? We can save the original method implementation in a variable and use it in our new implementation. The best way to get the original method is to access metaClass and invoke the getMetaMethod() method. We save this method in a variable. In the new implementatation we can use the invoke() method on the saved method to invoke the original code.

def savedToUpperCase = String.metaClass.getMetaMethod('toUpperCase', [] as Class[])
String.metaClass.toUpperCase = { -> 
    def result = savedToUpperCase.invoke(delegate)    
    if (delegate =~ /Groovy/) {
        result + ' Oh, yeah man! Groooovy...'
    } else {
        result
    }
}

assert 'A SIMPLE STRING' == 'A simple string'.toUpperCase()
assert 'THIS IS GROOVY. Oh, yeah man! Groooovy...' == 'This is Groovy.'.toUpperCase()

December 20, 2009

Groovy Goodness: Adding or Overriding Methods with ExpandoMetaClass

In Groovy we can add new methods to classes with ExpandoMetaClass using the leftShift (<<) operator. If the method already exists we get an error. To override an existing method we can use the equal operator (=). But we can also use the equal operator (=) to add a new method, but then we don't get an error when the method already exists.

Integer.metaClass.eights << { delegate * 8 }
assert 32 == 4.eights()

Integer.metaClass.hundreds = { delegate * 100 }
assert 200 == 2.hundreds()

try {
    Integer.metaClass.toString << { 'Groovy' } // Cannot use << for existing method.
    assert false
} catch (e) {
    assert 'Cannot add new method [toString] for arguments [[]]. It already exists!' == e.message
}

Integer.metaClass.toString = { 'Groovy' }
assert 'Groovy' == 100.toString()

December 19, 2009

Groovy Goodness: Get Properties from ReleaseInfo

We can use the ReleaseInfo class to get the Groovy version we are running our application in.

// We run this code with Groovy 1.6.7, see assertions.
import org.codehaus.groovy.util.ReleaseInfo

assert '1.6.7' == ReleaseInfo.version
assert '1.6.7' == ReleaseInfo['ImplementationVersion']
assert '12:40 PM' == ReleaseInfo.get('BuildTime')
assert '1.6.7' == ReleaseInfo.get('BundleVersion')
assert '02-Dez-2009' == ReleaseInfo['BuildDate']

December 18, 2009

Groovy Goodness: Getting Groovy with DOM

Reading XML is easy with Groovy's XmlParser, XmlSlurper classes. But sometimes we get an XML structure as DOM from another application or Java component. So we need more low-level access at the DOM level: we are in a world of nodes and elements. We can use the DOMCategory to make the low-level handling more Groovy.

import groovy.xml.*
import groovy.xml.dom.*

def xml = '''
<users>
    <user active="true">
        <fullname>mrhaki</fullname>
    </user>
    <user active="false">
        <fullname>Hubert A. Klein Ikkink</fullname>
    </user>
</users>
'''
def xmlDom = DOMBuilder.newInstance().parseText(xml)  // Create DOM structure.

def root = xmlDom.documentElement
use (DOMCategory) {
    def users = root.user
    assert 2 == users.size()
    
    assert 'User with fullname mrhaki is active' == userInfo(users[0])
    assert 'User with fullname Hubert A. Klein Ikkink is not active' == userInfo(users[1])

    assert 'mrhaki' == users.findAll { it.'@active'.toBoolean() }[0].fullname.text()
}

def userInfo(user) {
    def active = user.'@active'.toBoolean()
    def fullname = user.fullname.text()
    "User with fullname $fullname is ${active ? 'active' : 'not active'}"
}

December 17, 2009

Groovy Goodness: Splitting with Closures

Groovy adds a split() method to objects with a closure parameter. In the closure we must define a condition to split up the items in two lists. One list contains all the items that apply to the closure condition, the other list contains the rest of the items that don't apply to the closure condition.

def range = 1..10
def (even, odd) = range.split { it % 2 == 0 }
assert [2,4,6,8,10] == even
assert [1,3,5,7,9] == odd

def map = [language: 'Groovy', username: 'mrhaki', age: 36]
def (strings, others) = map.split { it.value instanceof String } 
assert 2 == strings.size()
assert 1 == others.size()
assert 'language' == strings[0].key && 'Groovy' == strings[0].value 
assert 'username' == strings[1].key && 'mrhaki' == strings[1].value 
assert 'age' == others[0].key && 36 == others[0].value

December 16, 2009

Grails Goodness: Cleaning Up Before WAR Creation

Grails provides a mechanism where we can execute a closure to do stuff before we create a WAR file. Technically speaking we can change the contents of the staging directory. So when we run the application as an exploded WAR file or we create a WAR file in both cases the closure is executed.

The closure is very useful to delete files we don't want to be in the final WAR file, but are copied by default. We define the closure in conf/BuildConfig.groovy and it must be named grails.war.resources. The closure has a parameter which is the staging directory. The context of the closure is AntBuilder, so all methods we define in the closure are executed for an AntBuilder object. For example if we normally would use the following statement: ant.echo(message: 'Hello'), we must now use echo(message: 'Hello'). The ant object is implicit for the context of the closure.

In the following sample we want to delete the Thumbs.db files Windows generates from the application:

// File: conf/BuildConfig.groovy
grails.war.resources = { stagingDir ->
    echo message: "StagingDir: $stagingDir"
    delete(verbose: true) {
        fileset(dir: stagingDir) {
            include name: '**/Thumbs.db'
        }
    }
}

Groovy Goodness: Getting Information About Objects

To get some information about an object we often use the toString() method in Java. In Groovy we can use the same toString() method, but we have two more alternatives. We can use the dump() method on an object and we get information about the name of the object, the hashcode and the values of the fields. And we can use the inspect() method, which will try to return a String which matches closest what we would type in Groovy code to create the object.

def map = [username: 'mrhaki']
assert '["username":"mrhaki"]' == map.inspect()

def list = [1, 2, 3, 'Groovy']
assert '[1, 2, 3, "Groovy"]' == list.inspect()

def range = 0..10
assert '0..10' == range.inspect()

def str = 'Inspecting object with Groovy'
assert '"Inspecting object with Groovy"' == str.inspect()

def dom = groovy.xml.DOMBuilder.newInstance().parseText('<root><language>Groovy</language></root>')
println dom.documentElement.inspect()
// Output:
// <?xml version="1.0" encoding="UTF-8"?>
// <root>
//   <language>Groovy</language>
// </root>

December 15, 2009

Groovy Goodness: Groovy Mystic Expressions

With Groovy we can omit parenthesis in some cases, key-value parameters for a method are grouped into a group. If we combine all these features we can come up with some pretty mystic expressions. But it is also perfect for writing DSLs, because it doesn't look like real Java/Groovy code anymore. Here is a small sample of an expression that looks strange at first, but at a second look we can see the structure of method calls:

result = []

// Mystic expressions: (see assert for outcome)
say hello:world {
    'Groovy'
}
say hello:world { 
    'Java' 
}

assert "Say 'Hello Groovy world!'" == result[0]
assert "Say 'Hello Java world!'" == result[1]

// Actually we are invoking:
// say([hello: world({ 'Groovy' })])
// say([hello: world({ 'Java' })])
// We notice two methods: save(map) and world(closure).

// The methods:
def world(callable) {
    def result = callable()
    "Hello $result world!"
}

def say(map) {
    result << "Say '${map.hello}'"
}

December 14, 2009

Grails Goodness: Change Context Path of a Grails Application for Jetty

By default a Grails application context path is set to the application name. The context path is the bold part in the following URL: http://localhost:8888/appname/index. We can change the context path with properties for when we use $ grails run-app to run the application. We can run $ grails -Dapp.context=/app run-app to change the context path to /app. Or we can set the property app.context = /app in application.properties. Or we can add grails.app.context = '/app' to our conf/Config.groovy configuration file. These properties will all affect the context path when we run $ grails run-app.

But what if we want to deploy our application to Jetty on a production server and use a custom context path? We have to add an extra file to web-app/WEB-INF with the name jetty-web.xml. Here we can configure Jetty specific settings for the application and one of the settings is the context path. If the application is deployed to Jetty or we run the application with $ grails run-app the context path is used that we set in jetty-web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: web-app/WEB-INF/jetty-web.xml -->
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
    <Set name="contextPath">/app</Set>
</Configure>

Weekly Sightings

Video of Google Chrome Features
A very artistic video showing Google Chrome features. The camera shows suprising angles on different scenes.

Getting Local Git Repo to the Server

Just a little remainder to myself on how to get my local Git repository to the server. The server repository can be accessed through SSH to push and pull changes. The steps are easy, but I always have to Google for it when I need to follow the steps, because I can't remember them. So now I only have to look at my own blog to get the correct steps.

$ mkdir projectdir
$ cd projectdir
$ git init
$ touch README
$ git add README
$ git commit -m "Initial commit"
$ cd ..
$ git clone --bare projectdir projectdir.git
$ scp -r projectdir.git user@server.com:/git-repo
$ cd projectdir
$ git remote add origin ssh://user@server.com/git-repo/projectdir.git
Now we can use $ git push to push changes to the server.
And we can use $ git clone user@server.com/git-repo/projectdir.git to clone the server repository on a local computer.

Groovy Goodness: Add Static Methods with MetaClass to Classes

Groovy's dynamic nature makes it easy to extend classes with new behaviour. One of the ways is to add methods or property to the metaClass property of a class. We can use the same mechanism to add static methods to the class. We only have to specify the keyword 'static' when we define the new method.

class User {
    String username, email
    String toString() { "$username, $email" }
}

User.metaClass.static.new = { u, e ->
    new User(username: u, email: e)
}

def u = User.new('mrhaki', 'mail@host.com')
assert 'mrhaki' == u.username
assert 'mail@host.com' == u.email
​

December 13, 2009

Grails Goodness: Add a DailyRollingFileAppender to Grails Logging

In Grails we can add new Log4J appenders to our configuration. We must add the new appender definition in the log4j closure in conf/Config.groovy. We define new appenders with the appenders() method. We pass in a closure where we define our appenders. The name of the appender is an identifier we can use when we want to define the log level and packages that need to be logged by the appender.

In the following sample configuration we create a DailyRollingFileAppender so each day a new log file is created and old log files are renamed with the date in the filename. Then we use the root() method to pass a closure telling we want to log all messages at level INFO to the appender.

// File: conf/Config.groovy
import org.apache.log4j.DailyRollingFileAppender

log4j = {
    appenders {
        appender new DailyRollingFileAppender(
            name: 'dailyAppender',
            datePattern: "'.'yyyy-MM-dd",  // See the API for all patterns.
            fileName: "logs/${appName}.log",
            layout: pattern(conversionPattern:'%d [%t] %-5p %c{2} %x - %m%n')        
        )
    }
    
    root {
        info 'dailyAppender'
    }    
}

Groovy Goodness: Info About Closure Parameters

We can inspect the number and type of parameters defined for a closure very easily. A closure has the properties maximumNumberOfParameters and parameterTypes for this. So in our code we can ask a closure how many parameters are expected and even which type the parameters are.

// Two simple closure with one and two parameters.
def one = { it.toUpperCase() }
def two = { String s, upper ->
    if (upper) {
        s.toUpperCase()
    } else {
        s.toLowerCase()
    }
}

def runClosure(cl) {
    switch (cl.maximumNumberOfParameters) {
        case 1: 
            assert [java.lang.Object] == cl.parameterTypes
            cl.call('Groovy')
            break
        case 2:
            assert [java.lang.String, java.lang.Object] == cl.parameterTypes
            cl('Groovy', false)
            break
    } 
}

assert 'GROOVY' == runClosure(one)
assert 'groovy' == runClosure(two)

December 12, 2009

Groovy Goodness: Getting the Sum of Items in a Collection

Update for this post Revisited Getting Sum of Items in a Collection.

In Groovy we can sum up the elements in a Collection with the sum() methods. We can use the variant without arguments, but also the one with one argument. The argument is the initial value for the sum value. The sum() method invokes the plus() method on the elements in the collection.

def numbers = [1, 2, 3, 4, 5, 6]
assert 21 == numbers.sum()
assert 31 == numbers.sum(10)

class Product {
    String name
    BigDecimal price

    BigDecimal plus(Product other) {
        price + other.price
    }
}
def products = [new Product(name: 'laptop', price: 999), new Product(name: 'netbook', price: 395)]

assert 1394 == products.sum()

December 11, 2009

Groovy Goodness: Formatted Strings with sprintf

Groovy adds the sprintf() method to the Object class. This means we can use the method in all of the classes, because it is defined at the top of the hierarchy. The sprintf() method uses the Java Formatter syntax to format values. We get a String as a result from the method.


assert 'Groovy is cool!' == sprintf( '%2$s %3$s %1$s', ['cool!', 'Groovy', 'is'])
assert '00042' == sprintf('%05d', 42)

December 10, 2009

Groovy Goodness: Delete Non-empty Directory Recursively with File

Groovy enhances the File class with several methods. One is the deleteDir() method. With this method we can delete a directory with all it's subdirectories and files. So the directory doesn't need to be empty to run this method.

def mainDir = new File('test') 
def subDir = new File(mainDir, 'app')
def file = new File(subDir, 'test.txt')

subDir.mkdirs()  // Create directories.
file << 'sample'  // Create file and add contents.

assert mainDir.exists() && subDir.exists() && file.exists()

def result = mainDir.deleteDir()  // Returns true if all goes well, false otherwise.
assert result
assert !mainDir.exists() && !subDir.exists() && !file.exists() 

December 9, 2009

Groovy Goodness: Type Conversion Using GPathResult When Reading XML

To read XML we can use the XmlSlurper class and we get a GPathResult object back. With GPathResult we can traverse throught the XML and get values from elements and attributes. GPathResult contains several method to convert values to specific classes, like toBoolean(), toString(), toInteger() and more.

def xml = '''
<users>
    <user loggedin="true">
        <age>36</age>
        <name>mrhaki</name>
        <fullname>Hubert A. Klein Ikkink</fullname>
        <homepage>http://www.mrhaki.com/</homepage>
    </user>
</users>
'''

def users = new XmlSlurper().parseText(xml)
def mrhaki = users.user[0]
assert mrhaki.@loggedin.toBoolean() 
assert 36 == mrhaki.age.toInteger()
assert 'mrhaki' == mrhaki.name.toString()
assert new URL('http://www.mrhaki.com/') == mrhaki.homepage.toURL()

December 8, 2009

Groovy Goodness: Semicolons are Optional

In Groovy we can leave out semicolons at the end of the line. As long as we use one statement per line. If we use multiple statements on a line we must use a semicolon to separate the statements.

assert true
assert !false

assert true; assert !false  // Need semicolon to separate statements.

assert true;  // Optional, so we can use them at the end of the line.
assert !false;

December 7, 2009

Groovy Goodness: Counting the Items in a List

In Groovy we can count how many thimes a specific object is in a list. We use the count() method on the list, iterator or array to achieve this. We must specify one parameter: the object we want to count. Groovy uses the compareTo or equals() method to check for equality.

def list = [0, 1, 2, 1, 1, 3, 2, 0, 1]

assert 9 == list.size()
assert 2 == list.count(0)
assert 4 == list.count(1)
assert 2 == list.count(2)
assert 1 == list.count(3)

December 6, 2009

Groovy Goodness: Add Methods to Interfaces with ExpandoMetaClass

We can add new behaviour to classes with the ExpandoMetaClass, but we can do the same for interfaces. We can add new methods to interfaces through the metaClass property.

interface Nothing { }
class Simple implements Nothing { }

Nothing.metaClass.groovyShoutOut = { -> "Groovy is awesome!" }

def s = new Simple()
assert 'Groovy is awesome!' == s.groovyShoutOut()

December 5, 2009

Groovy Goodness: Know More About a Class

In Groovy we can use the Java reflection API to examine our classes. Groovy makes it a bit easier because we can access properties the Groovy way. And because we can call methods and properties directly on the class instead of the class property. We can still go the route through the class property, but it is optional.

interface Simple {}
class Sample implements Simple {
    String info
    String displayInfo() { "info from $Sample.name" }
}

assert 'Sample' == Sample.name
assert 'Sample' == Sample.class.name

def interfaces = Sample.interfaces.name
assert 'Simple' in interfaces
assert 'groovy.lang.GroovyObject' in interfaces

def methods = Sample.methods.name
assert 'setInfo' in methods
assert 'getInfo' in methods
assert 'displayInfo' in methods

def s = new Sample()
assert 'info from Sample' == s.displayInfo()

December 4, 2009

Groovy Goodness: Using the ServletCategory

In the groovy.servlet package we can find the class ServletCategory. We can use this class to access attributes on the servlet context, page context, request and session with the dot notation. The methods putAt and getAt are implemented in this class for all four objects. If we write Groovy code in the context of these object we can use the ServletCategory to make the code more Groovy.

In the following sample we write two servlets that use the ServletCategory to write and read attribute values. We compile the code to Java classes to get executable servlet. Finally we write a Groovy script to run Jetty with our servlets.

// File: Start.groovy
import javax.servlet.http.*
import javax.servlet.*
import groovy.servlet.ServletCategory

class Start extends HttpServlet {
    def application 
    
    void init(ServletConfig config) {
        super.init(config)
        application = config.servletContext
        use(ServletCategory) {
            application.author = 'mrhaki'
        }
    }
    
    void doGet(HttpServletRequest request, HttpServletRespons response) {
        def session = request.session
        use (ServletCategory) {
            if (session.counter) {  // We can use . notation to access session attribute.
                session.counter++  // We can use . notation to set value for session attribute.
            } else {
                session.counter = 1
            }
            
            request.pageTitle = 'Groovy Rocks!'
        }
        application.getRequestDispatcher('/output').forward(request, response)
    }
}
// File: Output.groovy
import javax.servlet.http.*
import javax.servlet.*
import groovy.xml.*
import groovy.servlet.ServletCategory

class Output extends HttpServlet {
    def context 
    
    void init(ServletConfig config) {
        super.init(config)
        context = config.servletContext
    }
    
    void doGet(HttpServletRequest request, HttpServletRespons reponse) {
        def html = new MarkupBuilder(response.writer)
        def session = request.session
        
        use(ServletCategory) {
            html.html {
                head {
                    title request.pageTitle
                }
                body {
                    h1 request.pageTitle 
                    h2 "$context.version written by $context.author"
                    p "You have requested this page $session.counter times."
                }
            }
        }
        
    }
}
// File: run.groovy
import org.mortbay.jetty.*
import org.mortbay.jetty.servlet.*
import groovy.servlet.*

@Grab(group='org.mortbay.jetty', module='jetty-embedded', version='6.1.14')
def startJetty() {
    def jetty = new Server(9090)
    def context = new Context(jetty, '/', Context.SESSIONS)
    context.resourceBase = '.'
    context.addServlet Start, '/start'
    context.addServlet Output, '/output'
    context.setAttribute 'version', '1.0'
    jetty.start()
}

startJetty()

In our web browser we open http://localhost:9090/start and get the following output:

December 3, 2009

Groovy Goodness: Implicit Method doCall in Closure

After reading Mixing dynamic and static code in Groovy I learned about the implicit method available in a closure: doCall(). This method corresponds to the arguments and body of the closure. If we invoke a closure with the call() or the unnamed () syntax the doCall() method is invoked. We can use this method to run the closure from within the closure.

def sizeList = { list, counter = 0 ->
    if (list.size() == 0) {
        counter
    } else {
        doCall(list.tail(), counter + 1)  // Call closure self.
    }
}

assert 5 == sizeList([1,2,3,4,5])

December 2, 2009

Groovy Goodness: Automatic Return Value Casting

If Groovy knows the return type of a method it will automatically cast our return value to that type. We don't have to explicitly cast our value.

String simple() {
    42
}
assert 'java.lang.String' == simple().class.name 
assert '42' == simple()

class User {
    String name, email
}

User createUser() { 
    [name: 'mrhaki', email: 'mail@host.com']
}
assert createUser() instanceof User
assert 'mrhaki' == createUser().name
assert 'mail@host.com' == createUser().email

December 1, 2009

Grails Goodness: Mocking the Configuration in Unit Tests

When we write a unit test for our Grails service and in the service we use ConfigurationHolder.config to get the Grails configuration we get null for the config object when we run the unit test. Which is fine for a unit test, because we want to provide values for the configuration in our test. This is easy to do: we use the mockConfig method to set configuration values for the unit test. The method accepts a String that is a configuration script.

// File: grails-app/services/SimpleService.groovy
import org.codehaus.groovy.grails.common.ConfigurationHolder as GrailsConfig

class SimpleService {
    String say(text) {
        "$GrailsConfig.config.simple.greeting $text"
    }
    
    String sayConfig() {
        say(GrailsConfig.config.simple.text)
    }
}
// File: test/unit/SimpleServiceTests.groovy
import grails.test.*

class SimpleServiceTests extends GrailsUnitTestCase {
    def service
    
    protected void setUp() {
        super.setUp()
        service = new SimpleService()
        
        mockConfig('''
            simple {
                greeting = 'Hello'
                text = 'world.'
            }
        ''')
    }
    
    protected void tearDown() {
        super.tearDown()
        service = null
    }
    
    void testSayConfig() {
        assertEquals 'Hello world.', service.sayConfig()
    }
    
    void testSay() {
        assertEquals 'Hello mrhaki', service.say('mrhaki')
    }
}

Groovy Goodness: ServerSocket Scripts

One of the Groovy commandline arguments is -l to start Groovy in server listening mode. We can provide a script that is read and executed while Groovy is running. The script is read each time for a new request, so we can keep Groovy running and change the script. Next time a new client connects to the server Groovy will use the new script.

In the script we have extra properties we can use. The init property is true if the script hasn't run yet for the client connection. We can check for init to run initializing code. The property socket contains the Socket for the server. The property out is set to a PrintWriter we can use to output information back to the client. Because the name is out we can use the println() method to send text back to the client. And finally we have the property line with the contents of the input (closed by a line ending) sent to the server script. To stop the client client connection from the server script we must return the String success from our script. This will close the client connection.

// File: SimpleServer.groovy

// The code block will be executed once.
if (init) {
    meta = [:]
    // We can access the socket in our script.
    meta.host = socket.inetAddress.hostAddress
}

// The line contains a single line of input from the client.
// If line starts with the text OUTPUT we output all gathered meta 
// information and close the client connection.
if (line.startsWith('OUTPUT')) {
    println()
    println "Server running on $meta.host"
    println "Meta info:"
    println "----------"
    meta.each { key, value -> 
        println "$key = $value"
    }
    println()
    return "success"  // Close client connection
} else {
    // Build meta information map.
    metaInfo = line.tokenize(":")  // Input meta information as key:value
    meta[metaInfo[0]] = metaInfo[1]
}

Now we can run the server with Groovy:

$ groovy -l 9010 SimpleServer.groovy
groovy is listening on port 9090

And we can test the server with telnet:

$ telnet localhost 9010
Trying 127.0.0.1...
Connected to localhost
Escape character is '^]'.
test:true
username:mrhaki
language:Groovy
OUTPUT

Server running on 127.0.0.1
Meta info:
----------
host = 127.0.0.1
test = true
username = mrhaki
language = Groovy

Connection closed by foreign host.