Interceptando métodos inexistentes em Groovy 2

As linguagens dinâmicas estão ganhando um espaço considerável hoje em dia. Para dar um exemplo do poder dessas linguagens, criei um exemplo simples em Groovy (linguagem Java que roda “em cima” da JVM).

Uma das características dessas linguagens, é poder aproveitar a criatividade do desenvolvedor. Daí temos como exemplo uma função que pode ser definida em nossos objetos chamada methodMissing. Essa função é chamada quando algum método não encontrado é chamado em algum objeto. Caso não seja definida, aí sim temos o comportamento padrão do Java, uma exception apontando a falta do método.

No twitter, o @cmilfont perguntou ao @fabiokung sobre um builder de HTML que ele tinha feito em ruby com o mesmo princípio. Usar o methodMissing. Quando eu vi este builder, fiquei pasmo com a simplicidade e objetividade, e tudo isso originou este post. Coloquei alguns tratamentos que não existiam, para valores de atributos das tags.

O exemplo utiliza o poder da função methodMissing para criar um “Builder”, ou então um construtor de HTML dinâmico com base em pseudo-métodos chamados pelo cliente. Imaginem a função abaixo:

def methodMissing(String name, params) {
	if (params[0] instanceof Closure) {
		println "< ${name}>"
		params[0].call()
		println "< / ${name}>"
	} else if (params[0] instanceof String) {
		println "< ${name}>${params[0]}< ${name}>"
	} else if (params[0] instanceof Map) {
		print "< ${name}"
		params[0].each() {chave, valor ->
			print " ${chave}=\"${valor}\""
		}
		if (params.length > 1) {
			if (params[1] instanceof Closure) {
				println ">"
				params[1].call()
				println ""
			}
		} else println " />"
	}
}

No primeiro if, resgatando o parâmetro do tipo closure, apenas faz a chamada a esta closure, para que o novo método seja chamado entre “TAGS” que são o nome do método criado dinâmicamente… Já no caso do parâmetro ser uma String, é encarada como conteúdo inteno da tag e renderizada desta maneira.

Se um map for passado como parâmetro, a interpretação é tida como vários atributos da tag html (método inexistente), e caso ainda tenhamos uma outra closure ali como parâmetro, o comportamento é repetido :)

Com este exemplo, poderíamos construir um simples HTML com o seguinte trecho de código (script) groovy:

html {
    head {
        title "teste de titulo"
    }
    body {
        div(id:3, class:"odd") {
            p "meu texto"
        }
        div id:5, class:"xpto"
    }
}

Prontinho, a JVM com o trecho acima cria nosso super-mega-ultra-elaborado trecho de HTML:

< html >
< head >
< title >teste de titulo< / title >
< / head >
< body >
< div id="3" class="odd" >
< p >meu texto< / p >< / div >
< div id="5" class="xpto" / >
< / body >
< / html >

Groovy é uma linguagem de script muito bacana e poderosa, e como roda em cima da JVM, não é nada mais que Java puro. Pode com certeza e MUITA eficiência substituir aqueles scripts shell que temos em algumas aplicações, trazendo para os desenvolvedores mais liberdade (de chamar um jar com funcionalidades, por exemplo), e conforto (de não depender de alguém de infra estrutura, ou de conhecimento em shell script).

Fica aí a dica e o exemplo do poder…

Valeu!

Understanding Groovy Categories 5

Have you ever used Groovy Categories? Do you even know what its stands for?

Groovy Categories is a great feature from Groovy (inherted from Objective-C) that allows you to have some kind of “extended” control on a class. The category just “add” some more funcionality to your class when you want. It’s different from creating another class that extends from the first one, this approach holds a little more functionality-oriented talk… :)

Categories is nothing more than a Groovy class that you’ve implemented before that effectly adds your functionality. The syntax is very simple and all you have to do, is tell to the runtime environment you’re now using the category.

use (the category class you want to use) {
    //all your code here can access the category funcionality
}
//back to normal code

That’s it. Groovy Core comes with some Categories (ServletCategory, DOMCategory and TimeCategory). The one we use more is the TimeCategory, that adds some calculation methods for us.

Let’s imagine we want to add some days in our current date, using Java you remember how you should do, don’t you?

Get a Calendar Instance, retrieve this calendar’s date, add the ammount of days using the strangest and creepiest method ever and then get the calendar’s date again (actually, get only its time and create a date with it):

//creepiest method
myCalendarInstance.add(Calendar.DAY_OF_MONTH, 10);

You can see in the TimeCategory’s javadoc (link above) that it defines some methods like “getHours(), getDays(), getMinutes()”. This methods we don’t have in some usual Date class, but when we use the TimeCategory object, they just get available for us. The example below show us what should happen when we use the TimeCategory:

Date now = new Date()
println now //just show when am I :) 

use(org.codehaus.groovy.runtime.TimeCategory) {
    now = now + 15.days
}

println now //shows us when we'll be in 15 days!

This will be our output after running this small script:

Sat May 02 02:25:57 BRT 2009
Sun May 17 02:25:57 BRT 2009

That’s it, try the code above and the others methods the TimeCategory gives to you: years, months, hours, minutes and seconds.

Thanks! Be the first to know when I publish some interesting article signing up my feed and following me on twitter!

Working with Excel and Grails 2

I found this 2 links in grailsbrasil.com forum.
It’s a nice feature to include in your system for that situations when user have to input a large amount of data.

First example shows how user can upload the excel file, and your system automatically load all the spreadsheet data into domain objects. And this one, shows the reverse way, by loading your domain objects into an excel file using JExcelAPI.

Recommend!

[]s,

[2/25] Searchable: Full text indexed search in grails 13

Are you reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

Introduction

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.5.3
Plugin Docs: http://www.grails.org/plugin/searchable
Download resources: source code screencast

-

Overview

The Searchable Plugin provides integration between Grails and, IMO, one of the most powerful open source libraries that we have. The Apache Lucene Project. I must admit that I’m a Lucene Lover, since my last project where I was leading a technical team for the largest brazilian e-commerce company and fourth worldwide. The project was totally lucene-driven to store everything you see there (yes, no database, believe me!); products, prices, categories, everything. Of course, the integration processes running backstage took all responsibility for update product prices and other stuff. For this project, we also used other important frameworks such as Apache Solr. I recommend you all look into Apache Lucene. It’s the base of the Compass Project, that is the framework that the Searchable Plugin integrates into our app.

All of this will provide us an excellent indexing tool to index our domain classes that will be searchable across our application. Searching in the Lucene index is infinitely lighter and faster than doing a “LIKE” select in any kind of relational database, and that’s why it is so awesome. So, let’s do it!

-

Download and Install

To do this example, we’ll create an application that searches in our posts archive! I’ll not save a lot of fake news articles in our bootstrap (as everybody is used to). I’ll use this tutorial to also show how to read a remote feed/rss! So, I will ask technorati what people are writing about groovy, and we’ll search on this database, I believ that this is a more realistic example :)

We’ll have a simple Post class that has only the post title, link and text, and make it searchable.

Creating the application

grails create-app postsearch
cd postsearch
grails install-plugin searchable
grails create-domain-class Post

This is the Post class

class Post {
    String title
    String link
    String body

    static searchable = true
    static constraints = {
        //constraints...
    }
}

Note that doing this:

static searchable = true

we are telling the searchable plugin that all instances of this domain class have to be indexed so we can search it later.

Take a look, now in action:

screencast

-

Technorati Integration

To get the technorati feed we’ll use to search, I build a simple class that will get the search results feed and iterate over the results and save one post for each entry. On technorati, I’ll search the following words: groovy, grails, java, griffon, springsource, g2one, acegi, groovyws, and codehaus. This will give us approximately 200 posts. I’ll create a simple controller that will just do this.

grails create-controller technorati

and this is its content

class TechnoratiController {
    def index = {
        def totalPosts = 0
        def wordList = ['groovy', 'grails', 'java', 'griffon', 'springsource',
                'g2one', 'acegi', 'groovyws', 'codehaus'].each() { word ->
            def rss = "http://feeds.technorati.com/search/${word}"
            def rssObj = new XmlSlurper().parse(rss)
            rssObj.channel.item.each { item ->
                def post = new Post(title: item.title.toString(),
                        link: item.link.toString(),
                        body: item.description.toString())
                if (post.save())
                    totalPosts++
            }
        }
        render "${totalPosts} posts indexed"
    }
}

Maybe we can turn this into a plugin later! :) That’s it, no view for it, we just need to request it to feed our database.

-

Searching with SearchController

After this you can go to the SearchableController that is installed in our application:

http://localhost:8080/postsearch/searchable

Try searching for “grails” or any other word that may have been in our technorati posts.

Note that this view uses the toString() method, so lets beautify it.

String toString() {
    return "${title}: ${body}"
}

SearchController screen

-

Changing the way fields are indexed

Our Post class is indexed using the default configuration for the Searchable plugin and that’s not the best way since the post URL is indexed as well and currently has the same relevance as its title (this is wrong, believe me). IMO, the link should not be indexed, just the title and the text of the post, and the title is much more important that its description.

To do this, we’ll use some plugin options. This plugin has A LOT of options, (it deserves a book of it, really), and all the options are described here. I strongly recommend you to read this if you use this plugin in your production environment.

Here we’ll just stick to the basics, we’ll exclude some properties being indexed and boost one field (title) that is more important. This means that when you search for “grails”, posts with “grails” in the title will come with a higher score than posts with “grails” only in the body of it.

Excluding link from being indexed

This is easy! We’ll change the static searchable = true for this one with the ‘except’ property.

static searchable = {
    except = ['link']
}

That’s it, no link will be indexed anymore. It’s recommended to index ONLY properties you really ‘ll need, otherwise your lucene index can grow to be quite large.

Boosting the title

This is easier (I don’t remember anything difficult using grails) than the last one, we’ll add the property boost to our title, and this is the final mapping closure:

static searchable = {
    except = ['link']
    title boost: 2.0
}

This will give our searches what we really want.

-

Searching – Domain classes

After installed, the plugins offer us (for domain classes marked as searchable) some methods that will search on the index. Here I’ll explain some of the most important ones.

search

The main method of this plugin. Will search across all instances of this domain class for the requested string (and options)

def postsListSeachResult = Post.search("grails")
def postsListOrderedSearchResult = Post.search("grails", [sort: 'title'])

Remember that ordering searches is not a good idea since you will lose all effective relevance-based scoring that lucene gives to each hit entry.

countHits

This method returns just the number of hits that your query retrieved in the index, useful to know how many entries will be returned if the search method was used instead. You can use as search method.

[groovy]def postsListSeachResultCount = Post.countHits("grails")
def postsListOrderedSearchResultCount = Post.countHits("grails", [sort: 'title'])

moreLikeThis and suggestQuery

“moreLikeThis” and “suggestQuery” (aka spell checking) can be done easily with Seachable Plugin, all you have to do is set these properties to the mapping closure.

Take a look here and here for more information.

-

Conclusion

This plugin is one of my favorites. If you’re planning a grails website in a production environment, this one will be your friend.

Ohh remember that this plugin is much more powerful than shown here, most configuration options available for Compass and Lucene have not been demonstrated here. This is just a small part of it!

Are you reading my blog’s feed? Be the first to know when I publish some interesting article signing up my feed and following me on twitter!

Last Tutorial:  [1/25] Acegi: Secure your grails application with no pain

Next Tutorial: [3/25] Quartz: Easy job scheduling plugin.

Another groovier way to access some itens in my list. 0

Hello,

Yesterday I’ve posted this post: Uma maneira bem ‘a-lá groovy’ de se acessar o último elemento de uma lista! (English version here) that explains how we can use negative indexes to access the elements on one list using groovy. And a friend of mine, Paulo Suzart, that works with me commented that using Scala he can have some extra calls one one list.

lista.head //first element
lista.last //last element
lista.tail //all elements except the first one

I myself do not know scala well, ( except for the times he keeps talking about it! LOL). But this comments submitted me to my textmate to explore the list methods, and I got surprised when I saw all that methods exactly reproduced in groovy. My mistake that I did not posted this way in yesterday’s post, but here it is:

def lista = []
lista << “first element”
lista << “second element”
lista << “third element”

println lista.head() //”first element”
println lista.last() //”third element”
println lista.tail() //gives me another list, formed by “second element” and “third element”

That’s it! Hope it helps.

You can follow me on twitter: twitter.com/lucastex

Grails 1.1 is available! 0

Hello!

Good news for today!! I just got @ work and saw in my twitter that Graeme Rocher just updated Grails with the new Version 1.1. This is awesome!!

Here is his twitt: http://twitter.com/graemerocher/status/1305118282
Grails 1.1 release notes: http://www.grails.org/1.1+Release+Notes
Grails 1.1 documentation: http://grails.org/doc/1.1.x/

Some stuff I really liked and I thing will help the day-by-day development:

  • GORM is now independent from Grails
    • Yeah, that is correct, now you can use GORM’s god-blessed-methods in your own groovy project!
  • hasMany associations for primitive types
    • You can use hasMany for primitive types, eg. Strings. Remember that time you had to create one domain class just for encapsulate one string? Now you can have this! :D
  • Global plugins
    • For people that knows Ruby and Rails, this will be like a gem. You install the plugin once with the tag -global and will be available for all apps

Visit the links above and stay tuned!

You can follow me on twitter: http://twitter.com/lucastex
Take care!

Uma maneira bem ‘a-lá groovy’ de se acessar o último elemento de uma lista! 3

Oi,

Brincando com groovy e lendo alguns artigos durante o fim de semana na internet, vi umas coisas bacanas que facilitam o uso desta linguagem!

Uma coisa que achei bem legal foi uma dica de como acessar uma lista “de trás pra frente”. Isso mesmo, as vezes a gente precisa acessar o último elemento de uma lista certo? Como faríamos?

Vamos imaginar a lista abaixo:

def lista = []
lista << “first item”
lista << “second item”
lista << “third item”

Se eu quisesse imprimir seu conteudo para verificar, teria:

println lista[0] // “first item”
println lista[1] // “second item”
println lista[2] // “third item”

Para acessar o último termo, sem delongas iríamos ter que chamar posicionalmente o último elemento da lista, e para isso teríamos que conhecer seu tamanho. Teríamos:

lista.get(lista.size()-1); //Java
lista[lista.size -1] //groovy

Certo? A coisa bacana é que groovy tem todos os índices de um array/lista espelhados para a sua forma negativa. Ou seja. Se você acessar a segunda posição (lista[1]), irá ir para frente com o número inteiro. Se acessar a segunda posição negativa (lista[-2]), irá percorrer o segundo elemento de trás para frente!

Ou seja, para acessar o último elemento da lista, a forma mais rápida, fácil e com cheiro de groovy é fazer:

println lista[-1] //”third item”

Bacana hein! Valeu!

[]s,

The grooviest way to access the last item in a list 1

Hey!

Do you know that groovy provides a fuuny way to access the last item in a list? Let’s say you have the snippet above:

def lista = []
lista << “first item”
lista << “second item”
lista << “third item”

println lista[0] // “first item”
println lista[1] // “second item”
println lista[2] // “third item”

That’s ok hã. If you are using Java and needs to access the last item in this list, what should you do? I bet would be something like this (that is applicable to groovy):

lista.get(lista.size()-1); //Java
lista[lista.size -1] //groovy

I said “applicable” but doing this does not make me feel “groovier”… How about this trick?

lista[-1] //”third item”

That’s it! The indexes inside a list in groovy are “mirrored” backwards, so you can access the “first item from back to front” using the first negative integer! This is applicable to the rest of the entries:

println lista[-1] // “third item”
println lista[-2] // “second item”
println lista[-3] // “first item”

Take care!

[]s,

Tempo livre…. 0

Tenho tido algum tempo livre… :)

Estou estudando bastante Ruby/Rails e Groovy/Grails.

Ando falando com o kico e acho que vou aproveitar um pouco do tempo livre pra dar uma mão no projeto do grailsbrasil… Andei colocando alguma coisa interessante por lá…

[]s,

Web Analytics