R – groovy closure parameters

closuresgroovy

The following example of using the sendMail method provided by the grails mail plugin appears in this book.

sendMail {
    to "foo@example.org"
    subject "Registration Complete"
    body view:"/foo/bar", model:[user:new User()]
}

I understand that the code within {} is a closure that is passed to sendMail as a parameter. I also understand that to, subject and body are method calls.

I'm trying to figure out what the code that implements the sendMail method would look like, and my best guess is something like this:

MailService {

    String subject
    String recipient
    String view
    def model

    sendMail(closure) {
        closure.call()
        // Code to send the mail now that all the 
        // various properties have been set
    }

    to(recipient) {
        this.recipient = recipient
    }

    subject(subject) {
        this.subject = subject;
    }

    body(view, model) {
        this.view = view
        this.model = model
    }
}

Is this reasonable, or am I missing something? In particular, are the methods invokedwithin the closure (to, subject, body), necessarily members of the same class as sendMail?

Thanks,
Don

Best Answer

MailService.sendMail closure delegating:

 MailMessage sendMail(Closure callable) {
    def messageBuilder = new MailMessageBuilder(this, mailSender)
    callable.delegate = messageBuilder
    callable.resolveStrategy = Closure.DELEGATE_FIRST
    callable.call()

    def message = messageBuilder.createMessage()
    initMessage(message)
    sendMail message
    return message
}

and for example, the method to at MailMessageBuilder:

void to(recip) {
    if(recip) {
        if (ConfigurationHolder.config.grails.mail.overrideAddress)
            recip = ConfigurationHolder.config.grails.mail.overrideAddress
        getMessage().setTo([recip.toString()] as String[])
    }
}