Arturo Herrero

Create your own Groovy type conversion

Type conversion, the standard way

Type conversion -or casting- is a programming language technique for changing an object’s data type into another.

I’m sure you are familiar with this code, which converts a String to an Integer.

def number = (Integer)'1'
def number = '1'.toInteger()
def number = '1' as Integer

If we want to change the type of my own objects, we need to create a method to achieve this goal. We can copy object properties to another object in a generic way; if a property exists on target object, we can copy it from the source object.

class User {
    String name
    String city
    Integer age

    def toAdminUser() {
        def adminUser = new AdminUser()
        copyProperties(this, adminUser)
        return adminUser
    }

    def copyProperties(source, target) {
        source.properties.each { key, value ->
            if (target.hasProperty(key) && !(key in ['class', 'metaClass'])) {
                target[key] = value
            }
        }
    }
}

class AdminUser {
    String name
    String city
    Integer age
}

It is now possible to do something like this:

adminUser = user.toAdminUser()

Type conversion, the fancy way

Great, but we may want to use this fancy way to coerce one type into another:

adminUser = user as AdminUser

Simple: Groovy supports operator overloading and, therefore, creating your own type conversion is really easy - we can override the asType() method.

class User {
    String name
    String city
    Integer age

    Object asType(Class clazz) {
        if (clazz == AdminUser) {
            def adminUser = new AdminUser()
            copyProperties(this, adminUser)
            return adminUser
        }
        else {
            super.asType(clazz)
        }
    }

    def copyProperties(source, target) {
        source.properties.each { key, value ->
            if (target.hasProperty(key) && !(key in ['class', 'metaClass'])) {
                target[key] = value
            }
        }
    }
}

February 06, 2012 | @ArturoHerrero