Técnico

Groovy XmlSlurper & invokeMethod

Grande parte do dinamismo do groovy se deve ao invokeMethod. Quando declarado, este método será executado caso um método inexistente for chamado no objeto em questão (Method missing no Ruby ou Python).

“invokeMethod(String name, Object args) is at the heart of Groovy metaprogramming.”, Groovy Recipes

Vamos ao exemplo:


class Sample {
Object invokeMethod( String name, Object params ) {
println "method ${name} with params ${params}"
}
}

Podemos agora chamar qualquer método em um objeto Sample:

def sample = new Sample()
sample.anything "arg1", "arg2"

E devido ao “method missing” do groovy, podemos navegar em um XML de forma elegante usando o XmlSlurper (navegação semelhante ao E4X):


def xml = """


Bruno
[email protected]


Fuster
[email protected]


"""

def users = new XmlSlurper().parseText(xml)

//para cada user no xml
users.user.each { user ->
println [email protected]
println user.name
}

No código acima estamos acessando os elementos do XML através de um método ou atributo inexistente (users.user, user.name, [email protected]), o que seria impossível sem invokeMethod e getProperty usado pelo XmlSlurper em conjunto com GPath.

Também poderiamos utilizar bibliotecas Java (XStream, JDOM, etc) para serializar objetos para XML e vice-versa, mas vamos brincar com groovy agora para obter uma lista de objetos do xml acima:


def objects = users.user.collect { xmlUser ->
new User(id: [email protected], name: xmlUser.name, email: xmlUser.email)
}

E serializar objetos para XML/JSON fica fácil com grails.converters e content negotiation:


import grails.converters.*
...
def list = {
withFormat {
xml(contentType:"text/xml") {
render User.list() as XML
}
json(contentType:"text/json") {
render User.list() as JSON
}
}
}
...

Produtivo, não ?

Autor(a)

Bruno Fuster

Comentário (1)

  1. Douglas
    30 de março de 2010

    nossa Fuster, mto produtivo outro mundo, como as coisas ficam mais facil com o groovy, sucesso!!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *