Lucas Teixeira

@lucastex

Arquivo para a categoria ‘Groovy’

Criando um tipo de dados personalizado no Grails + Hibernate

com 11 comentários

Olá Pessoal,

Estou invadindo o Blog do meu grande amigo Lucas para postar uma solução que encontrei para um problema no mapeamento de dados de uma base de dados existente. Gostaria, em primeiro lugar, de agradecer o espaço cedido pelo Lucas e parabenizá-lo pelo excelente Blog.

Hoje em dia são poucos os projetos que precisamos desenvolver do zero — criar modelagem, tabelas e etc… — por isso é muito comum depararmos com padrões proprietários que muitas vezes não se “encaixam” na ferramenta de desenvolvimento. Não preciso dizer que não é uma tarefa fácil convencer os desenvolvedores a se adequarem aos novos padrões, então, se não pode com eles, una-se a eles.

Bom, vamos direto ao assunto, no meu projeto atual me deparei com um padrão que utiliza ‘S’ e ‘N’ para o mapeamento de propriedades booleanas no banco de dados Oracle. Na pesquisa que realizei encontrei várias pseudo-soluções mas a única que atendeu 100% as necessidades foi a implementação de um tipo de dados do Hibernate.

Abaixo a implementação da classe SNUserType, não tem segredo é apenas a implementação da interface org.hibernate.usertype.UserType. Salve este código no pacote persistence na pasta de src/groovy do seu projeto Grails.

package persistence;

import org.hibernate.*;
import org.hibernate.usertype.*;
import java.sql.*;
import java.util.*;
import java.io.Serializable;

public class SNUserType implements UserType {

   def SQL_TYPES = [Hibernate.YES_NO.sqlType()];

   public int[] sqlTypes() {
      return SQL_TYPES;
   }

   private Class targetClass;

   public void setParameterValues(Properties params) {
      String targetClassName = params.getProperty("targetClass");
      try {
         targetClass = Class.forName(targetClassName);
      } catch (ClassNotFoundException e) {
         throw new HibernateException("Class " + targetClassName + " not found ", e);
      }
   }

   public Class returnedClass() {
      return targetClass;
   }

   public boolean isMutable() {
      return false;
   }

   public Object deepCopy(Object value) {
      return value;
   }

   public Serializable disassemble(Object value) {
      return (Serializable) value;
   }

   public Object assemble(Serializable cached, Object owner) {
      return cached;
   }

   public Object replace(Object original, Object target, Object owner) {
      return original;
   }

   public boolean equals(Object x, Object y) {
      if (x == y)
         return true;
      if (x == null || y == null)
         return false;
      return x.equals(y);
   }

   public int hashCode(Object x) {
      return x.hashCode();
   }

   public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
      String value = rs.getString(names[0]);
      if ("S".equals(value))
         return true;
      else
         return false;
   }

   public void nullSafeSet(PreparedStatement ps, Object value, int index) throws HibernateException, SQLException {
      if (value == null) {
         ps.setNull(index, Hibernate.YES_NO.sqlType());
      } else {
         if((Boolean)value) {
            ps.setString(index, "S");
         } else {
            ps.setString(index, "N");
         }
      }
   }
}

Pronto, agora tudo que você precisa fazer é utilizar o novo tipo de dados no mapeamento de suas classes de domínio.

class Pessoa {

   String nome
   Boolean ativo

   static mapping = {
      ativo type: "persistence.SNUserType"
   }

}

Com isso, resolvi o problema de integração e concluímos este post.

Um abraço

Volnei

Written by Volnei Munhoz

July 19th, 2010 at 8:39 am

Config.groovy – Cuidado ao manipular suas configurações

com um comentário

Hum, reportando uma situação no mínimo inusitada que tive por aqui.

Acabei descobrindo, da maneira ruim, que no Grails, quando lêmos a configuração da aplicação (Config.groovy) através da referência grailsApplication.config estamos manipulando uma variável passível de alterações, ou seja, qualquer atributo que você recuperar de lá, e modificar, assim estará para toda a execução.

Na minha situação, eu mantinha uma lista de e-mails lá no arquivo de configuração para que quando disparado, eu pudesse enviar o e-mail a estes destinatários somados ao e-mail do usuário, que tinha acabado de ser inputado no formulário. Tinha algo assim:

contato.destinatarios = ["[email protected]", "[email protected]", "[email protected]"]

E dentro do controller, usando o mail plugin (leia este post sobre o mail plugin), executava o seguinte trecho de código:

def destinatarios = grailsApplication.config.contato?.destinatarios?.toArray()
destinatarios << params.email
sendMail {
    to destinatarios
    subject "Contato ..."
    body "......"
 }

Ou seja, quando eu pegava a referência dos destinatários do Config, eu mantinha essa referência em ‘destinatários’. Quando eu adicionava neste array o destinatário que vinha do formulários “params.email”, eu alterava a *instância* e referência da configuração da aplicação, e aquele e-mail ali ficava.

Resultado, no primeiro contato, receberam o e-mail a lista de destinatários e o [email protected], na segunda execução, todos eles da configuração, o [email protected] e também o [email protected] foram copiados.

E assim sucessivamente.

Vivendo e aprendendo, tomem cuidado com isso!

Written by Lucas Teixeira

January 11th, 2010 at 10:18 pm

Portal imobiliário usando Groovy e Grails

com 24 comentários

Ontem (dia 09/01) fizemos o lançamento de um site que desenvolvemos usando Groovy e Grails, um desafio e tanto, pela responsabilidade de colocar o sistema no ar e pelo timing do projeto. Todo o site e a integração com o sistema legado (onde algumas informações ainda estão sendo gerenciadas), tiveram que sair do simples “create app” para produção em 2 meses. Esse é também o grande motivo para a falta de tempo de postar mais por aqui.

Trata-se dos sites http://www.imoveisnomorumbi.com.br e http://www.imoveisnopanamby.com.br, site de duas imobiliárias do mesmo grupo, que negocia imóveis de alto padrão nestes dois bairros.

Algumas informações interessantes sobre o projeto:

Tecnologia e Infraestrutura: O site antigo usava SQLServer como banco de dados e tecnologia ASP. Como usamos Groovy e Grails, por trás temos uma JVM Java em execução, e o banco de dados, o bom e velho MySQL.

Antes, para suportar o ASP, o IIS era usado como web server, e agora Um apache balanceia as requisições aos dois Tomcats. Tudo isto está deployado e rodando em um Cloud Server da Locaweb, por opção do cliente, onde já mantinha a conta antiga.

Integração com o sistema legado: Para a integração do modelo de dados antigo e o novo modelo, construímos rotinas de importação dos dados usando Groovy SQL, uma maneira  fácil, muito fácil, de fazer rotinas em banco de dados.

Plugins utilizados: Ahhh, os bons e velhos plugins do Grails, não canso de dizer que esta é a melhor parte do Grails! Foram usados os plugins:

Grails-Mail, para envio dos e-mails e formas de contato do site
Grails-Acegi, para autenticação e segurança
Grails-Cookie, para manipulação dos cookies do cliente
Grails-Navigation para criação de menus/submenus da interface administrativa
Grails-RichUi para alguns componentes gráficos como auto-complete e nuvem de tags
Grails-RuntimeLogging, um ótimo plugin para moder trabalhar com o nível de log de cada artefato (controller, service, etc), da app em runtime
Grails-Settings para algumas parametrizações da aplicação.

E com certeza, se eu tivesse pesquisado com um pouco mais de tempo, teria usado outros plugins para evitar algum trabalho que tenha feito na mão. E é claro, além disso, bastante (mesmo) jquery, ajax e json.

É isso, qualquer dúvida sobre o projeto, como aconteceu, soluções e problemas, basta comentar!

Obrigado a todos!

Written by Lucas Teixeira

January 10th, 2010 at 11:05 am

Gerenciamento de dependências com Grape

com 8 comentários

Mais uma maneira de se gerenciar dependências :)

Agora é a vez do Grape, um módulo construindo em Groovy que abstrai toda aquela configuração do maven/ivy que vc teria por padrão. O grande diferencial do Grape, é que ele traz essa configuração mais para perto de quem precisa dela, ou seja, no próprio código fonte!

Funciona basicamente assim, você anota o seu método que irá precisar da dependência com a anotação @Grab dizendo qual é o grupo, artefato e versão da biblioteca que você precisa e pronto! Quando a classe for carregada, esta anotação irá disparar o download desta dependência automaticamente. Os arquivos que são baixados via grape são guardados dentro do diretório do usuário na pasta .groovy/grapes

Segue um simples exemplo que depende do commons-lang 2.4 e usa um método simples da classe StringUtils para trocar o case de uma string.

import org.apache.commons.lang.StringUtils

@Grab(group='commons-lang', module='commons-lang', version='2.4')
void testGrape() {

   def name = "Lucas Frare Teixeira"
   println StringUtils.swapCase(name) //lUCAS fRARE tEIXEIRA

}

//Chama a execução do método
testGrape()

Veja que a únca coisa que precisamos fazer, é anotar o método com a dependência e ele fica responsável por fazer o download.

Mas, conversando com o @paulosuzart do CodeMountain, chegamos a conclusão, que sistemas de maior porte, merecem um controle de dependências mais centralizado e até por que não dizer, organizado.

Ou seja, fica a minha dica de uso do Grape para a distribuição de scripts e arquivos pequenos, para evitar aquela coisa chata de enviar jars, setar classpath, ou então ter arquivos pom que definem dependência e etc.

Para evitar esta dor de cabeça, sem dúvidas o grape é ideal!

Written by Lucas Teixeira

October 30th, 2009 at 3:47 pm

Postado em Groovy

Com as tags , , , ,

Maravilhas do Groovy: A propriedade metaClass

com 14 comentários

Uma das facilidades que o groovy também traz, é a possibilidade de adicionar métodos em nossas classes em tempo de execução através da propriedade metaClass dos objetos.

Agora mesmo, eu precisava de um recurso para criar “slugs” (essas URLs amigáveis que o WordPress cria) de titulos de artigos. Tradicionalmente, o processo é criar aquelas classes **Utils.java com todos os métodos utilitários, mas com a metaprogramação, o mais usual passa a ser adicionar o métodos nas próprias classes que geram este comportamento.

No exemplo abaixo, eu adicionei o método slug() em runtime dentro da classe String e a partir de agora, qualquer objeto da classe java.lang.String possui o método slug(), com o comportamento descrito abaixo.

String.metaClass.slug { ->
    def s = delegate.toLowerCase()
    s = s.replaceAll(/[^a-z0-9\s-]/, "").replaceAll(/\s+/, " ").trim()
    if (s.length() > 45)
        s = s.substring(0, 45).trim()
    s.replaceAll(/\s/, "-")
 }

Em primeiro, definimos uma varíavel interna ’s’ com o valor da própria string que está sendo usada (através da propriedade delegate), após isso, aplicamos a primeira regex de caracteres especiais, outra para substituir os espaços em excesso e cortamos a string caso ela tenha mais que 45 caracteres. Por fim, substituímos os espaços por dashes.

Você pode rodar este script neste endereço, basta clicar em “Execute script”

Written by Lucas Teixeira

October 25th, 2009 at 12:55 pm

Maravilhas do Groovy: Elvis Operator

com 8 comentários

Nova categoria de posts “Maravilhas do Groovy”, inspirada pelo MrHaki e seus posts sobre o diferencial e tricks que o groovy oferece.

O Elvis Operator é um operador em Groovy (já estará embutido no Java7) representado pelo “ponto de interrogação” seguido pelos caracteres “dois pontos” ou seja  ?:

O objetivo é fazer a comparação do valor de uma referencia a null, para decidir sobre uma atribuição de valor. Um exemplo bem comum é comparar o um parametro que vem do request de qual página irá ser mostrada de uma lista de objetos, porém, caso a página não esteja presente, devemos sempre mostrar a primeira página.

Tradicionalmente, em java, com o operador ternário:

Integer pageParam = (...)
pageParam = (pageParam == null) ? 1 : pageparam;

Com o elvis operator, ele já faz esta comparação implicitamente e caso o valor da variável seja null, recebe o valor que está a direita do operador.

def pageParam = (...)
pageParam = pageParam ?: 1

— Post editado as 18:10 do dia 22/10 —
Meu amigo @paulosuzart do CodeMountain fez um post sobre o Elvis Operator em Scala.
A gente sabe que não existe, mas ele criou um. Vale a pena conferir. :)

Written by Lucas Teixeira

October 22nd, 2009 at 12:09 pm

Não tenha medo das closures

com 13 comentários

Você tem medo das closures? Já vi muita gente dizer que closures são perigosas e trazê-las a tona seria como acordar um monstro adormecido (o medonho GOTO – veja uma ótima definição neste link).

Não eu não concordo, closures só querem o seu bem, eis a razão.

Bom, uma closure nada mais é que um trecho de código! Mas o que difere este bloco de instruções chamado closure de um método? A grande diferença neste caso, é que as closures são um pouco mais flexíveis que os métodos, e por sua vez podem até ser passadas como parâmetro na chamada de outras funções, ou seja, podem ser atribuídas a uma variável.

Em java não temos closures nativas na linguagem, e uma das formas de tentar alcançar o objetivo é através do uso de classes anônimas, o que particularmente não me agrada muito, pela sujeira que fica no código.

Em um primeiro exemplo, mais simples, segue como definir uma closure, associá-la a uma variável e depois executá-la. (exemplo em groovy).

def c = {
    println "Testando o uso de uma closure"
}
c.call()

Este é um exemplo simples, onde a frase acima será impressa no console.

Para incrementarmos um pouco, podemos fazer com que nossa closure receba um parâmetro para usá-lo dentro da execução, além de criar um método que faça o uso dela. O exemplo abaixo mostra isto.

//definição da closure para dizer oi
def ola = { nome ->
    println "E ai ${nome}, tudo bom?"
}

//definição da closure para dizer tchau
def tchau = { nome ->
    println "To indo ${nome}, ate a proxima!"
}

//criação do método que fará o uso da closure
void falar(Closure c, String paraQuem) {
    c.call(paraQuem)
}

//invoke do método com as closures de parametro
//note que a closure é passada como se fosse uma variável qualquer
falar(ola, "Fulano")
falar(tchau, "Ciclano")

Mas uma das maiores vantagens que eu enxergo nas closures, é a possibilidade de definição delas em runtime. Isso mesmo, conforme você programa, pode criar uma nova closure e chamar uma função que precise dela! Vemos isso em ruby e groovy com frequência para métodos onde iteramos listas e mapas.

Por exemplo, as listas e arrays em groovy possuem um método each que recebe uma closure como parâmetro, esta closure define o que será feito com cada um dos items da lista/array em questão. O exemplo abaixo mostra a praticidade de se fazer a definição da closure inline, ou seja, sem criar uma variável para ela antes.

Em groovy

//groovy
def lista = ["Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams"]
lista.each { equipe ->
    println "A equipe ${equipe} correu na #F1 em 2009"
}

Em ruby

#ruby
lista = ["Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams"]
lista.each { |equipe|
    puts "A equipe #{equipe} correu na #F1 em 2009"
}

Em scala

//scala
val teams = List("Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams")
teams foreach {
   team => printf("A equipe %s correu na #F1 em 2009", team)
}

Dá pra perceber que a closure foi criada já no momento em que ela foi usada. Desta maneira, além de fácil, um código muito mais limpo e fácil de ser entendido.

Acredite, closures são suas amigas, e estão aqui pra te ajudar, então aproveite!

Ahh, e fica a dica de sempre: Ler a documentação:

Closures em Groovy (wiki) (groovydoc) (definição formal)
Closures (Proc) em Ruby (doc) (wiki)
Closures em Scala (wiki)

Written by Lucas Teixeira

October 21st, 2009 at 11:55 am

Postado em Groovy, Ruby, Scala

Com as tags , , , ,

Get Adobe Flash playerPlugin by wpburn.com wordpress themes