The following example of using the sendMail method provided by the grails mail plugin appears in this book.
sendMail {
to "[email protected]"
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
A closure is an anonymous block of code.
6) Mention what is the role of closure and listeners in Groovy? Groovy does not support anonymous inner classes; it is possible to determine action listeners inline through the means of closures. In Groovy, listeners closure are used as a ListenerAdapter where only one method of interest is overridden.
Inject is the groovy way to do a left fold. Left fold is basically iterating over a list from the head and applying a function to the current element and the accumulated value.
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[])
}
}
I'm not sure exactly what the sendMail method does as I do not have the book you mention. The sendMail method does indeed take a closure as you describe but it probably uses a builder rather than being executed in the normal way. Essentially that would be a Domain Specific Language for describing an email to be sent.
The reason the class you defined would not work is that the scope of the closure is where it is declared not where it is run. So having your closure call the to() method, it would not be able to call the to method in MailService unless you passed the instance of mail service into the closure.
With a few modifications, your example could work though using a regular closure. The following changes to the call and
// The it-> can be omitted but I put it in here so you can see the parameter
service.sendMail {it->
it.to "[email protected]"
it.subject "Registration Complete"
it.body view:"/foo/bar", model:[user:new User()]
}
The sendMail method in the class should look like this
def sendMail(closure) {
closure(this)
// Code to send the mail now that all the
// various properties have been set
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With