Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I override the 'map' constructor in a Grails domain class?

I need to perform some initialization when new instances of my domain class are created.

class ActivationToken {
    String foo
    String bar
}

When I do this I want bar to be initialized by code inside ActivationToken:

def tok = new ActivationToken(foo:'a')

I cannot see how to 'override' the 'constructor' to make this happen. I know in this case I could just add a normal constructor but this is just a simple example.

like image 801
David Tinker Avatar asked Sep 13 '11 10:09

David Tinker


2 Answers

The map constructor is coming from Groovy - not Grails in this case. I did some experimentation, and this is what I came up with:

class Foo {
    String name = "bob"
    int num = 0

    public Foo() {
        this([:])
    }

    public Foo(Map map) {
        map?.each { k, v -> this[k] = v }
        name = name.toUpperCase()
    }

    public String toString() {
        "$name=$num"
    }
}

assert 'BOB=0' == new Foo().toString()
assert 'JOE=32' == new Foo(name:"joe", num: 32).toString()

Basically, it appears that you'll have to manually override the constructors if you need to process the property after construction.

Alternately, you can override individual setters, which is cleaner and safer in general:

class Foo {
    String name = "bob"
    int num = 0

    public void setName(n) {   
        name = n.toUpperCase()
    }

    public String toString() {
        "$name=$num"
    }
}

assert 'bob=0' == new Foo().toString()
assert 'JOE=32' == new Foo(name:"joe", num: 32).toString()

Note that the default value isn't processed, but that should be OK in most instances.

like image 62
OverZealous Avatar answered Sep 28 '22 00:09

OverZealous


The solution above is also good for cases where initializing an object from parameters in a web request, for example, where you wish to ignore extraneous values, catching Missing property exceptions.

public Foo(Map map) {
    try {
        map?.each { k, v -> this[k] = v }
    }
    catch(Exception e){
    }
}
like image 34
bill Avatar answered Sep 28 '22 00:09

bill